blob: d9affe39ea77e24846f762037520ba18ee7d97f9 [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
10514 const CompletionCallback& callback() const { return callback_; }
10515
10516 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:2010517 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310518 callback_ = callback;
10519 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,
10525 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310526 return ERR_FAILED;
10527 }
10528
10529 private:
10530 CompletionCallback callback_;
10531 };
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.
10556 ASSERT_FALSE(fake_reader->callback().is_null());
10557
10558 // Return Init()'s result after the transaction gets destroyed.
10559 trans.reset();
10560 fake_reader->callback().Run(OK); // Should not crash.
10561}
10562
[email protected]aeefc9e82010-02-19 16:18:2710563// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110564TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710565 HttpRequestInfo request;
10566 request.method = "GET";
bncce36dca22015-04-21 22:11:2310567 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:2710568
10569 // First transaction will request a resource and receive a Basic challenge
10570 // with realm="first_realm".
10571 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310572 MockWrite(
10573 "GET / HTTP/1.1\r\n"
10574 "Host: www.example.org\r\n"
10575 "Connection: keep-alive\r\n"
10576 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710577 };
10578 MockRead data_reads1[] = {
10579 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10580 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10581 "\r\n"),
10582 };
10583
bnc691fda62016-08-12 00:43:1610584 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710585 // for first_realm. The server will reject and provide a challenge with
10586 // second_realm.
10587 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310588 MockWrite(
10589 "GET / HTTP/1.1\r\n"
10590 "Host: www.example.org\r\n"
10591 "Connection: keep-alive\r\n"
10592 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10593 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710594 };
10595 MockRead data_reads2[] = {
10596 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10597 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10598 "\r\n"),
10599 };
10600
10601 // This again fails, and goes back to first_realm. Make sure that the
10602 // entry is removed from cache.
10603 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310604 MockWrite(
10605 "GET / HTTP/1.1\r\n"
10606 "Host: www.example.org\r\n"
10607 "Connection: keep-alive\r\n"
10608 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10609 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710610 };
10611 MockRead data_reads3[] = {
10612 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10613 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10614 "\r\n"),
10615 };
10616
10617 // Try one last time (with the correct password) and get the resource.
10618 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310619 MockWrite(
10620 "GET / HTTP/1.1\r\n"
10621 "Host: www.example.org\r\n"
10622 "Connection: keep-alive\r\n"
10623 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10624 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710625 };
10626 MockRead data_reads4[] = {
10627 MockRead("HTTP/1.1 200 OK\r\n"
10628 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010629 "Content-Length: 5\r\n"
10630 "\r\n"
10631 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710632 };
10633
10634 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10635 data_writes1, arraysize(data_writes1));
10636 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10637 data_writes2, arraysize(data_writes2));
10638 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10639 data_writes3, arraysize(data_writes3));
10640 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10641 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710642 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10643 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10644 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10645 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710646
[email protected]49639fa2011-12-20 23:22:4110647 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710648
danakj1fd259a02016-04-16 03:17:0910649 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610650 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010651
[email protected]aeefc9e82010-02-19 16:18:2710652 // Issue the first request with Authorize headers. There should be a
10653 // password prompt for first_realm waiting to be filled in after the
10654 // transaction completes.
tfarina42834112016-09-22 13:38:2010655 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710657 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110658 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610659 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210660 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410661 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210662 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410663 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310664 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410665 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910666 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710667
10668 // Issue the second request with an incorrect password. There should be a
10669 // password prompt for second_realm waiting to be filled in after the
10670 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110671 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610672 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10673 callback2.callback());
robpercival214763f2016-07-01 23:27:0110674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710675 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110676 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610677 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210678 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410679 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210680 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410681 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310682 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410683 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910684 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710685
10686 // Issue the third request with another incorrect password. There should be
10687 // a password prompt for first_realm waiting to be filled in. If the password
10688 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10689 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110690 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610691 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10692 callback3.callback());
robpercival214763f2016-07-01 23:27:0110693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710694 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110695 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610696 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210697 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410698 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210699 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410700 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310701 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410702 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910703 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710704
10705 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110706 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610707 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10708 callback4.callback());
robpercival214763f2016-07-01 23:27:0110709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710710 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110711 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610712 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210713 ASSERT_TRUE(response);
10714 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710715}
10716
Bence Béky230ac612017-08-30 19:17:0810717// Regression test for https://crbug.com/754395.
10718TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10719 MockRead data_reads[] = {
10720 MockRead("HTTP/1.1 200 OK\r\n"),
10721 MockRead(kAlternativeServiceHttpHeader),
10722 MockRead("\r\n"),
10723 MockRead("hello world"),
10724 MockRead(SYNCHRONOUS, OK),
10725 };
10726
10727 HttpRequestInfo request;
10728 request.method = "GET";
10729 request.url = GURL("https://www.example.org/");
10730
10731 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10732 session_deps_.socket_factory->AddSocketDataProvider(&data);
10733
10734 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910735 ssl.ssl_info.cert =
10736 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10737 ASSERT_TRUE(ssl.ssl_info.cert);
10738 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0810739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10740
10741 TestCompletionCallback callback;
10742
10743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10745
10746 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10748
10749 url::SchemeHostPort test_server(request.url);
10750 HttpServerProperties* http_server_properties =
10751 session->http_server_properties();
10752 EXPECT_TRUE(
10753 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10754
10755 EXPECT_THAT(callback.WaitForResult(), IsOk());
10756
10757 const HttpResponseInfo* response = trans.GetResponseInfo();
10758 ASSERT_TRUE(response);
10759 ASSERT_TRUE(response->headers);
10760 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10761 EXPECT_FALSE(response->was_fetched_via_spdy);
10762 EXPECT_FALSE(response->was_alpn_negotiated);
10763
10764 std::string response_data;
10765 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10766 EXPECT_EQ("hello world", response_data);
10767
10768 EXPECT_TRUE(
10769 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10770}
10771
bncd16676a2016-07-20 16:23:0110772TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210773 MockRead data_reads[] = {
10774 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310775 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210776 MockRead("\r\n"),
10777 MockRead("hello world"),
10778 MockRead(SYNCHRONOUS, OK),
10779 };
10780
10781 HttpRequestInfo request;
10782 request.method = "GET";
bncb26024382016-06-29 02:39:4510783 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210784
10785 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210786 session_deps_.socket_factory->AddSocketDataProvider(&data);
10787
bncb26024382016-06-29 02:39:4510788 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910789 ssl.ssl_info.cert =
10790 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10791 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510792 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10793
bncc958faa2015-07-31 18:14:5210794 TestCompletionCallback callback;
10795
danakj1fd259a02016-04-16 03:17:0910796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210798
tfarina42834112016-09-22 13:38:2010799 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210801
bncb26024382016-06-29 02:39:4510802 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010803 HttpServerProperties* http_server_properties =
10804 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410805 EXPECT_TRUE(
10806 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210807
robpercival214763f2016-07-01 23:27:0110808 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210809
bnc691fda62016-08-12 00:43:1610810 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210811 ASSERT_TRUE(response);
10812 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210813 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10814 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210815 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210816
10817 std::string response_data;
bnc691fda62016-08-12 00:43:1610818 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210819 EXPECT_EQ("hello world", response_data);
10820
zhongyic4de03032017-05-19 04:07:3410821 AlternativeServiceInfoVector alternative_service_info_vector =
10822 http_server_properties->GetAlternativeServiceInfos(test_server);
10823 ASSERT_EQ(1u, alternative_service_info_vector.size());
10824 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10825 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410826 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210827}
10828
bnce3dd56f2016-06-01 10:37:1110829// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110830TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110831 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110832 MockRead data_reads[] = {
10833 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310834 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110835 MockRead("\r\n"),
10836 MockRead("hello world"),
10837 MockRead(SYNCHRONOUS, OK),
10838 };
10839
10840 HttpRequestInfo request;
10841 request.method = "GET";
10842 request.url = GURL("http://www.example.org/");
10843 request.load_flags = 0;
10844
10845 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10846 session_deps_.socket_factory->AddSocketDataProvider(&data);
10847
10848 TestCompletionCallback callback;
10849
10850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610851 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110852
10853 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010854 HttpServerProperties* http_server_properties =
10855 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410856 EXPECT_TRUE(
10857 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110858
tfarina42834112016-09-22 13:38:2010859 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10861 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110862
bnc691fda62016-08-12 00:43:1610863 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110864 ASSERT_TRUE(response);
10865 ASSERT_TRUE(response->headers);
10866 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10867 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210868 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110869
10870 std::string response_data;
bnc691fda62016-08-12 00:43:1610871 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110872 EXPECT_EQ("hello world", response_data);
10873
zhongyic4de03032017-05-19 04:07:3410874 EXPECT_TRUE(
10875 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110876}
10877
bnca86731e2017-04-17 12:31:2810878// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510879// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110880TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510881 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810882 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510883
bnc8bef8da22016-05-30 01:28:2510884 HttpRequestInfo request;
10885 request.method = "GET";
bncb26024382016-06-29 02:39:4510886 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510887 request.load_flags = 0;
10888
10889 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10890 StaticSocketDataProvider first_data;
10891 first_data.set_connect_data(mock_connect);
10892 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510893 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610894 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510895 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510896
10897 MockRead data_reads[] = {
10898 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10899 MockRead(ASYNC, OK),
10900 };
10901 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10902 0);
10903 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10904
10905 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10906
bnc525e175a2016-06-20 12:36:4010907 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510908 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110909 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10910 444);
bnc8bef8da22016-05-30 01:28:2510911 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110912 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510913 url::SchemeHostPort(request.url), alternative_service, expiration);
10914
bnc691fda62016-08-12 00:43:1610915 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510916 TestCompletionCallback callback;
10917
tfarina42834112016-09-22 13:38:2010918 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510919 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110920 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510921}
10922
bnce3dd56f2016-06-01 10:37:1110923// Regression test for https://crbug.com/615497:
10924// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110925TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110926 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110927 HttpRequestInfo request;
10928 request.method = "GET";
10929 request.url = GURL("http://www.example.org/");
10930 request.load_flags = 0;
10931
10932 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10933 StaticSocketDataProvider first_data;
10934 first_data.set_connect_data(mock_connect);
10935 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10936
10937 MockRead data_reads[] = {
10938 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10939 MockRead(ASYNC, OK),
10940 };
10941 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10942 0);
10943 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10944
10945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10946
bnc525e175a2016-06-20 12:36:4010947 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110948 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110949 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110950 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110951 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110952 url::SchemeHostPort(request.url), alternative_service, expiration);
10953
bnc691fda62016-08-12 00:43:1610954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110955 TestCompletionCallback callback;
10956
tfarina42834112016-09-22 13:38:2010957 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110958 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110959 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110960}
10961
bncd16676a2016-07-20 16:23:0110962TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810963 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010965 HttpServerProperties* http_server_properties =
10966 session->http_server_properties();
bncb26024382016-06-29 02:39:4510967 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110968 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810969 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110970 http_server_properties->SetQuicAlternativeService(
10971 test_server, alternative_service, expiration,
10972 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410973 EXPECT_EQ(
10974 1u,
10975 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810976
10977 // Send a clear header.
10978 MockRead data_reads[] = {
10979 MockRead("HTTP/1.1 200 OK\r\n"),
10980 MockRead("Alt-Svc: clear\r\n"),
10981 MockRead("\r\n"),
10982 MockRead("hello world"),
10983 MockRead(SYNCHRONOUS, OK),
10984 };
10985 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10986 session_deps_.socket_factory->AddSocketDataProvider(&data);
10987
bncb26024382016-06-29 02:39:4510988 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910989 ssl.ssl_info.cert =
10990 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10991 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4510992 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10993
bnc4f575852015-10-14 18:35:0810994 HttpRequestInfo request;
10995 request.method = "GET";
bncb26024382016-06-29 02:39:4510996 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810997
10998 TestCompletionCallback callback;
10999
bnc691fda62016-08-12 00:43:1611000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811001
tfarina42834112016-09-22 13:38:2011002 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111003 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811004
bnc691fda62016-08-12 00:43:1611005 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211006 ASSERT_TRUE(response);
11007 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11009 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211010 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811011
11012 std::string response_data;
bnc691fda62016-08-12 00:43:1611013 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811014 EXPECT_EQ("hello world", response_data);
11015
zhongyic4de03032017-05-19 04:07:3411016 EXPECT_TRUE(
11017 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811018}
11019
bncd16676a2016-07-20 16:23:0111020TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211021 MockRead data_reads[] = {
11022 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311023 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11024 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211025 MockRead("hello world"),
11026 MockRead(SYNCHRONOUS, OK),
11027 };
11028
11029 HttpRequestInfo request;
11030 request.method = "GET";
bncb26024382016-06-29 02:39:4511031 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5211032
11033 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5211034 session_deps_.socket_factory->AddSocketDataProvider(&data);
11035
bncb26024382016-06-29 02:39:4511036 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911037 ssl.ssl_info.cert =
11038 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11039 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511040 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11041
bncc958faa2015-07-31 18:14:5211042 TestCompletionCallback callback;
11043
danakj1fd259a02016-04-16 03:17:0911044 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611045 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211046
tfarina42834112016-09-22 13:38:2011047 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111048 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211049
bncb26024382016-06-29 02:39:4511050 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011051 HttpServerProperties* http_server_properties =
11052 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411053 EXPECT_TRUE(
11054 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211055
robpercival214763f2016-07-01 23:27:0111056 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211057
bnc691fda62016-08-12 00:43:1611058 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211059 ASSERT_TRUE(response);
11060 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211061 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11062 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211063 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211064
11065 std::string response_data;
bnc691fda62016-08-12 00:43:1611066 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211067 EXPECT_EQ("hello world", response_data);
11068
zhongyic4de03032017-05-19 04:07:3411069 AlternativeServiceInfoVector alternative_service_info_vector =
11070 http_server_properties->GetAlternativeServiceInfos(test_server);
11071 ASSERT_EQ(2u, alternative_service_info_vector.size());
11072
11073 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11074 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411075 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411076 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11077 1234);
11078 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411079 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211080}
11081
bncd16676a2016-07-20 16:23:0111082TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611083 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211084 HostPortPair alternative("alternative.example.org", 443);
11085 std::string origin_url = "https://origin.example.org:443";
11086 std::string alternative_url = "https://alternative.example.org:443";
11087
11088 // Negotiate HTTP/1.1 with alternative.example.org.
11089 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611090 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211091 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11092
11093 // HTTP/1.1 data for request.
11094 MockWrite http_writes[] = {
11095 MockWrite("GET / HTTP/1.1\r\n"
11096 "Host: alternative.example.org\r\n"
11097 "Connection: keep-alive\r\n\r\n"),
11098 };
11099
11100 MockRead http_reads[] = {
11101 MockRead("HTTP/1.1 200 OK\r\n"
11102 "Content-Type: text/html; charset=iso-8859-1\r\n"
11103 "Content-Length: 40\r\n\r\n"
11104 "first HTTP/1.1 response from alternative"),
11105 };
11106 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11107 http_writes, arraysize(http_writes));
11108 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11109
11110 StaticSocketDataProvider data_refused;
11111 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11112 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11113
zhongyi3d4a55e72016-04-22 20:36:4611114 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011116 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211117 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111118 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211119 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111120 http_server_properties->SetQuicAlternativeService(
11121 server, alternative_service, expiration,
11122 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211123 // Mark the QUIC alternative service as broken.
11124 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11125
zhongyi48704c182015-12-07 07:52:0211126 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211128 request.method = "GET";
11129 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211130 TestCompletionCallback callback;
11131 NetErrorDetails details;
11132 EXPECT_FALSE(details.quic_broken);
11133
tfarina42834112016-09-22 13:38:2011134 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611135 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211136 EXPECT_TRUE(details.quic_broken);
11137}
11138
bncd16676a2016-07-20 16:23:0111139TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611140 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211141 HostPortPair alternative1("alternative1.example.org", 443);
11142 HostPortPair alternative2("alternative2.example.org", 443);
11143 std::string origin_url = "https://origin.example.org:443";
11144 std::string alternative_url1 = "https://alternative1.example.org:443";
11145 std::string alternative_url2 = "https://alternative2.example.org:443";
11146
11147 // Negotiate HTTP/1.1 with alternative1.example.org.
11148 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611149 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211150 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11151
11152 // HTTP/1.1 data for request.
11153 MockWrite http_writes[] = {
11154 MockWrite("GET / HTTP/1.1\r\n"
11155 "Host: alternative1.example.org\r\n"
11156 "Connection: keep-alive\r\n\r\n"),
11157 };
11158
11159 MockRead http_reads[] = {
11160 MockRead("HTTP/1.1 200 OK\r\n"
11161 "Content-Type: text/html; charset=iso-8859-1\r\n"
11162 "Content-Length: 40\r\n\r\n"
11163 "first HTTP/1.1 response from alternative1"),
11164 };
11165 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11166 http_writes, arraysize(http_writes));
11167 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11168
11169 StaticSocketDataProvider data_refused;
11170 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11171 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11172
danakj1fd259a02016-04-16 03:17:0911173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011174 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211175 session->http_server_properties();
11176
zhongyi3d4a55e72016-04-22 20:36:4611177 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211178 AlternativeServiceInfoVector alternative_service_info_vector;
11179 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11180
bnc3472afd2016-11-17 15:27:2111181 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111182 alternative_service_info_vector.push_back(
11183 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11184 alternative_service1, expiration,
11185 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111186 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111187 alternative_service_info_vector.push_back(
11188 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11189 alternative_service2, expiration,
11190 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211191
11192 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611193 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211194
11195 // Mark one of the QUIC alternative service as broken.
11196 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411197 EXPECT_EQ(2u,
11198 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211199
zhongyi48704c182015-12-07 07:52:0211200 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211202 request.method = "GET";
11203 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0211204 TestCompletionCallback callback;
11205 NetErrorDetails details;
11206 EXPECT_FALSE(details.quic_broken);
11207
tfarina42834112016-09-22 13:38:2011208 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611209 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211210 EXPECT_FALSE(details.quic_broken);
11211}
11212
bncd16676a2016-07-20 16:23:0111213TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211214 HttpRequestInfo request;
11215 request.method = "GET";
bncb26024382016-06-29 02:39:4511216 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4211217
[email protected]d973e99a2012-02-17 21:02:3611218 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211219 StaticSocketDataProvider first_data;
11220 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711221 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511222 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611223 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211225
11226 MockRead data_reads[] = {
11227 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11228 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611229 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211230 };
11231 StaticSocketDataProvider second_data(
11232 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711233 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211234
danakj1fd259a02016-04-16 03:17:0911235 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211236
bnc525e175a2016-06-20 12:36:4011237 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311238 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611239 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111240 // Port must be < 1024, or the header will be ignored (since initial port was
11241 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111242 // Port is ignored by MockConnect anyway.
11243 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11244 666);
bnc7dc7e1b42015-07-28 14:43:1211245 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111246 http_server_properties->SetHttp2AlternativeService(
11247 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211248
bnc691fda62016-08-12 00:43:1611249 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111250 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211251
tfarina42834112016-09-22 13:38:2011252 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11254 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211255
bnc691fda62016-08-12 00:43:1611256 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211257 ASSERT_TRUE(response);
11258 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211259 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11260
11261 std::string response_data;
bnc691fda62016-08-12 00:43:1611262 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211263 EXPECT_EQ("hello world", response_data);
11264
zhongyic4de03032017-05-19 04:07:3411265 const AlternativeServiceInfoVector alternative_service_info_vector =
11266 http_server_properties->GetAlternativeServiceInfos(server);
11267 ASSERT_EQ(1u, alternative_service_info_vector.size());
11268 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411269 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411270 EXPECT_TRUE(
11271 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211272}
11273
bnc55ff9da2015-08-19 18:42:3511274// Ensure that we are not allowed to redirect traffic via an alternate protocol
11275// to an unrestricted (port >= 1024) when the original traffic was on a
11276// restricted port (port < 1024). Ensure that we can redirect in all other
11277// cases.
bncd16676a2016-07-20 16:23:0111278TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111279 HttpRequestInfo restricted_port_request;
11280 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511281 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111282 restricted_port_request.load_flags = 0;
11283
[email protected]d973e99a2012-02-17 21:02:3611284 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111285 StaticSocketDataProvider first_data;
11286 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711287 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111288
11289 MockRead data_reads[] = {
11290 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11291 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611292 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111293 };
11294 StaticSocketDataProvider second_data(
11295 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711296 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511297 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611298 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111300
danakj1fd259a02016-04-16 03:17:0911301 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111302
bnc525e175a2016-06-20 12:36:4011303 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311304 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111305 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111306 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11307 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211308 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111309 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611310 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011311 expiration);
[email protected]3912662a32011-10-04 00:51:1111312
bnc691fda62016-08-12 00:43:1611313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111314 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111315
tfarina42834112016-09-22 13:38:2011316 int rv = trans.Start(&restricted_port_request, callback.callback(),
11317 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111319 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111320 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911321}
[email protected]3912662a32011-10-04 00:51:1111322
bnc55ff9da2015-08-19 18:42:3511323// Ensure that we are allowed to redirect traffic via an alternate protocol to
11324// an unrestricted (port >= 1024) when the original traffic was on a restricted
11325// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111326TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711327 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911328
11329 HttpRequestInfo restricted_port_request;
11330 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511331 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911332 restricted_port_request.load_flags = 0;
11333
11334 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11335 StaticSocketDataProvider first_data;
11336 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711337 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911338
11339 MockRead data_reads[] = {
11340 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11341 MockRead("hello world"),
11342 MockRead(ASYNC, OK),
11343 };
11344 StaticSocketDataProvider second_data(
11345 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711346 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511347 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611348 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511349 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911350
danakj1fd259a02016-04-16 03:17:0911351 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911352
bnc525e175a2016-06-20 12:36:4011353 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911354 session->http_server_properties();
11355 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111356 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11357 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211358 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111359 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611360 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011361 expiration);
[email protected]c54c6962013-02-01 04:53:1911362
bnc691fda62016-08-12 00:43:1611363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911364 TestCompletionCallback callback;
11365
tfarina42834112016-09-22 13:38:2011366 EXPECT_EQ(ERR_IO_PENDING,
11367 trans.Start(&restricted_port_request, callback.callback(),
11368 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911369 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111370 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111371}
11372
bnc55ff9da2015-08-19 18:42:3511373// Ensure that we are not allowed to redirect traffic via an alternate protocol
11374// to an unrestricted (port >= 1024) when the original traffic was on a
11375// restricted port (port < 1024). Ensure that we can redirect in all other
11376// cases.
bncd16676a2016-07-20 16:23:0111377TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111378 HttpRequestInfo restricted_port_request;
11379 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511380 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111381 restricted_port_request.load_flags = 0;
11382
[email protected]d973e99a2012-02-17 21:02:3611383 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111384 StaticSocketDataProvider first_data;
11385 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711386 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111387
11388 MockRead data_reads[] = {
11389 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11390 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611391 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111392 };
11393 StaticSocketDataProvider second_data(
11394 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711395 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111396
bncb26024382016-06-29 02:39:4511397 SSLSocketDataProvider ssl(ASYNC, OK);
11398 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11399
danakj1fd259a02016-04-16 03:17:0911400 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111401
bnc525e175a2016-06-20 12:36:4011402 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311403 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111404 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111405 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11406 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211407 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111408 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611409 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011410 expiration);
[email protected]3912662a32011-10-04 00:51:1111411
bnc691fda62016-08-12 00:43:1611412 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111413 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111414
tfarina42834112016-09-22 13:38:2011415 int rv = trans.Start(&restricted_port_request, callback.callback(),
11416 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111417 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111418 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111419 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111420}
11421
bnc55ff9da2015-08-19 18:42:3511422// Ensure that we are not allowed to redirect traffic via an alternate protocol
11423// to an unrestricted (port >= 1024) when the original traffic was on a
11424// restricted port (port < 1024). Ensure that we can redirect in all other
11425// cases.
bncd16676a2016-07-20 16:23:0111426TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111427 HttpRequestInfo unrestricted_port_request;
11428 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511429 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111430 unrestricted_port_request.load_flags = 0;
11431
[email protected]d973e99a2012-02-17 21:02:3611432 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111433 StaticSocketDataProvider first_data;
11434 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711435 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111436
11437 MockRead data_reads[] = {
11438 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11439 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611440 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111441 };
11442 StaticSocketDataProvider second_data(
11443 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711444 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511445 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611446 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111448
danakj1fd259a02016-04-16 03:17:0911449 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111450
bnc525e175a2016-06-20 12:36:4011451 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311452 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111453 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111454 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11455 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211456 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111457 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611458 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011459 expiration);
[email protected]3912662a32011-10-04 00:51:1111460
bnc691fda62016-08-12 00:43:1611461 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111462 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111463
bnc691fda62016-08-12 00:43:1611464 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011465 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111467 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111468 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111469}
11470
bnc55ff9da2015-08-19 18:42:3511471// Ensure that we are not allowed to redirect traffic via an alternate protocol
11472// to an unrestricted (port >= 1024) when the original traffic was on a
11473// restricted port (port < 1024). Ensure that we can redirect in all other
11474// cases.
bncd16676a2016-07-20 16:23:0111475TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111476 HttpRequestInfo unrestricted_port_request;
11477 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511478 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111479 unrestricted_port_request.load_flags = 0;
11480
[email protected]d973e99a2012-02-17 21:02:3611481 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111482 StaticSocketDataProvider first_data;
11483 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711484 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111485
11486 MockRead data_reads[] = {
11487 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11488 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611489 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111490 };
11491 StaticSocketDataProvider second_data(
11492 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711493 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111494
bncb26024382016-06-29 02:39:4511495 SSLSocketDataProvider ssl(ASYNC, OK);
11496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11497
danakj1fd259a02016-04-16 03:17:0911498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111499
bnc525e175a2016-06-20 12:36:4011500 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311501 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211502 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111503 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11504 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211505 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111506 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611507 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011508 expiration);
[email protected]3912662a32011-10-04 00:51:1111509
bnc691fda62016-08-12 00:43:1611510 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111511 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111512
bnc691fda62016-08-12 00:43:1611513 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011514 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111515 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111516 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111517 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111518}
11519
bnc55ff9da2015-08-19 18:42:3511520// Ensure that we are not allowed to redirect traffic via an alternate protocol
11521// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11522// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111523TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211524 HttpRequestInfo request;
11525 request.method = "GET";
bncce36dca22015-04-21 22:11:2311526 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0211527
11528 // The alternate protocol request will error out before we attempt to connect,
11529 // so only the standard HTTP request will try to connect.
11530 MockRead data_reads[] = {
11531 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11532 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611533 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211534 };
11535 StaticSocketDataProvider data(
11536 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711537 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211538
danakj1fd259a02016-04-16 03:17:0911539 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211540
bnc525e175a2016-06-20 12:36:4011541 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211542 session->http_server_properties();
11543 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111544 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11545 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211546 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111547 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611548 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211549
bnc691fda62016-08-12 00:43:1611550 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211551 TestCompletionCallback callback;
11552
tfarina42834112016-09-22 13:38:2011553 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211555 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111556 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211557
bnc691fda62016-08-12 00:43:1611558 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211559 ASSERT_TRUE(response);
11560 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211561 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11562
11563 std::string response_data;
bnc691fda62016-08-12 00:43:1611564 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211565 EXPECT_EQ("hello world", response_data);
11566}
11567
bncd16676a2016-07-20 16:23:0111568TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411569 HttpRequestInfo request;
11570 request.method = "GET";
bncb26024382016-06-29 02:39:4511571 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411572
11573 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211574 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311575 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211576 MockRead("\r\n"),
11577 MockRead("hello world"),
11578 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11579 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411580
11581 StaticSocketDataProvider first_transaction(
11582 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711583 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511584 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611585 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511586 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411587
bnc032658ba2016-09-26 18:17:1511588 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411589
bncdf80d44fd2016-07-15 20:27:4111590 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511591 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111592 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411593
bnc42331402016-07-25 13:36:1511594 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111595 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411596 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111597 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411598 };
11599
rch8e6c6c42015-05-01 14:05:1311600 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11601 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711602 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411603
[email protected]d973e99a2012-02-17 21:02:3611604 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511605 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11606 NULL, 0, NULL, 0);
11607 hanging_non_alternate_protocol_socket.set_connect_data(
11608 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711609 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511610 &hanging_non_alternate_protocol_socket);
11611
[email protected]49639fa2011-12-20 23:22:4111612 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411613
danakj1fd259a02016-04-16 03:17:0911614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811615 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911616 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411617
tfarina42834112016-09-22 13:38:2011618 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11620 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411621
11622 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211623 ASSERT_TRUE(response);
11624 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411625 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11626
11627 std::string response_data;
robpercival214763f2016-07-01 23:27:0111628 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411629 EXPECT_EQ("hello world", response_data);
11630
bnc87dcefc2017-05-25 12:47:5811631 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911632 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411633
tfarina42834112016-09-22 13:38:2011634 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11636 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411637
11638 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211639 ASSERT_TRUE(response);
11640 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211641 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311642 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211643 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411644
robpercival214763f2016-07-01 23:27:0111645 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411646 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411647}
11648
bncd16676a2016-07-20 16:23:0111649TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511650 HttpRequestInfo request;
11651 request.method = "GET";
bncb26024382016-06-29 02:39:4511652 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511653
bncb26024382016-06-29 02:39:4511654 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511655 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211656 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311657 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211658 MockRead("\r\n"),
11659 MockRead("hello world"),
11660 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11661 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511662 };
11663
bncb26024382016-06-29 02:39:4511664 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11665 0);
11666 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511667
bncb26024382016-06-29 02:39:4511668 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911669 ssl_http11.ssl_info.cert =
11670 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11671 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511672 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11673
11674 // Second transaction starts an alternative and a non-alternative Job.
11675 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611676 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811677 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11678 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811679 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11680
11681 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11682 hanging_socket2.set_connect_data(never_finishing_connect);
11683 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511684
bncb26024382016-06-29 02:39:4511685 // Third transaction starts an alternative and a non-alternative job.
11686 // The non-alternative job hangs, but the alternative one succeeds.
11687 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111688 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511689 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111690 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511691 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511692 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111693 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511694 };
bnc42331402016-07-25 13:36:1511695 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111696 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511697 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111698 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511699 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111700 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11701 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311702 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511703 };
11704
rch8e6c6c42015-05-01 14:05:1311705 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11706 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711707 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511708
bnc032658ba2016-09-26 18:17:1511709 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511710
mmenkecc2298e2015-12-07 18:20:1811711 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11712 hanging_socket3.set_connect_data(never_finishing_connect);
11713 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511714
danakj1fd259a02016-04-16 03:17:0911715 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111716 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011717 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511718
tfarina42834112016-09-22 13:38:2011719 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11721 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511722
11723 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211724 ASSERT_TRUE(response);
11725 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511726 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11727
11728 std::string response_data;
robpercival214763f2016-07-01 23:27:0111729 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511730 EXPECT_EQ("hello world", response_data);
11731
[email protected]49639fa2011-12-20 23:22:4111732 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011733 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011734 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511736
[email protected]49639fa2011-12-20 23:22:4111737 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011738 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011739 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511741
robpercival214763f2016-07-01 23:27:0111742 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11743 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511744
11745 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211746 ASSERT_TRUE(response);
11747 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211748 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511749 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211750 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111751 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511752 EXPECT_EQ("hello!", response_data);
11753
11754 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211755 ASSERT_TRUE(response);
11756 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211757 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511758 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211759 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111760 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511761 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511762}
11763
bncd16676a2016-07-20 16:23:0111764TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511765 HttpRequestInfo request;
11766 request.method = "GET";
bncb26024382016-06-29 02:39:4511767 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511768
11769 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211770 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311771 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211772 MockRead("\r\n"),
11773 MockRead("hello world"),
11774 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11775 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511776 };
11777
11778 StaticSocketDataProvider first_transaction(
11779 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711780 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511781
[email protected]8ddf8322012-02-23 18:08:0611782 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911783 ssl.ssl_info.cert =
11784 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11785 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0711786 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511787
[email protected]d973e99a2012-02-17 21:02:3611788 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511789 StaticSocketDataProvider hanging_alternate_protocol_socket(
11790 NULL, 0, NULL, 0);
11791 hanging_alternate_protocol_socket.set_connect_data(
11792 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711793 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511794 &hanging_alternate_protocol_socket);
11795
bncb26024382016-06-29 02:39:4511796 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811797 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11798 NULL, 0);
11799 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511800 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511801
[email protected]49639fa2011-12-20 23:22:4111802 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511803
danakj1fd259a02016-04-16 03:17:0911804 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811805 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911806 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511807
tfarina42834112016-09-22 13:38:2011808 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111809 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11810 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511811
11812 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211813 ASSERT_TRUE(response);
11814 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511815 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11816
11817 std::string response_data;
robpercival214763f2016-07-01 23:27:0111818 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511819 EXPECT_EQ("hello world", response_data);
11820
bnc87dcefc2017-05-25 12:47:5811821 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911822 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511823
tfarina42834112016-09-22 13:38:2011824 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11826 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511827
11828 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211829 ASSERT_TRUE(response);
11830 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511831 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11832 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211833 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511834
robpercival214763f2016-07-01 23:27:0111835 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511836 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511837}
11838
[email protected]631f1322010-04-30 17:59:1111839class CapturingProxyResolver : public ProxyResolver {
11840 public:
Chris Watkins7a41d3552017-12-01 02:13:2711841 CapturingProxyResolver() = default;
11842 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1111843
dchengb03027d2014-10-21 12:00:2011844 int GetProxyForURL(const GURL& url,
11845 ProxyInfo* results,
11846 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511847 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011848 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011849 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11850 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211851 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111852 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211853 return OK;
[email protected]631f1322010-04-30 17:59:1111854 }
11855
[email protected]24476402010-07-20 20:55:1711856 const std::vector<GURL>& resolved() const { return resolved_; }
11857
11858 private:
[email protected]631f1322010-04-30 17:59:1111859 std::vector<GURL> resolved_;
11860
11861 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11862};
11863
sammce64b2362015-04-29 03:50:2311864class CapturingProxyResolverFactory : public ProxyResolverFactory {
11865 public:
11866 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11867 : ProxyResolverFactory(false), resolver_(resolver) {}
11868
11869 int CreateProxyResolver(
11870 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911871 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311872 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911873 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911874 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311875 return OK;
11876 }
11877
11878 private:
11879 ProxyResolver* resolver_;
11880};
11881
bnc2e884782016-08-11 19:45:1911882// Test that proxy is resolved using the origin url,
11883// regardless of the alternative server.
11884TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11885 // Configure proxy to bypass www.example.org, which is the origin URL.
11886 ProxyConfig proxy_config;
11887 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11888 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11889 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911890 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911891
11892 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911893 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911894 &capturing_proxy_resolver);
11895
11896 TestNetLog net_log;
11897
Lily Houghton8c2f97d2018-01-22 05:06:5911898 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
bnc2e884782016-08-11 19:45:1911899 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11900 &net_log);
11901
11902 session_deps_.net_log = &net_log;
11903
11904 // Configure alternative service with a hostname that is not bypassed by the
11905 // proxy.
11906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11907 HttpServerProperties* http_server_properties =
11908 session->http_server_properties();
11909 url::SchemeHostPort server("https", "www.example.org", 443);
11910 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111911 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911912 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111913 http_server_properties->SetHttp2AlternativeService(
11914 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911915
11916 // Non-alternative job should hang.
11917 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11918 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11919 nullptr, 0);
11920 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11921 session_deps_.socket_factory->AddSocketDataProvider(
11922 &hanging_alternate_protocol_socket);
11923
bnc032658ba2016-09-26 18:17:1511924 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911925
11926 HttpRequestInfo request;
11927 request.method = "GET";
11928 request.url = GURL("https://www.example.org/");
11929 request.load_flags = 0;
11930
11931 SpdySerializedFrame req(
11932 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11933
11934 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11935
11936 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11937 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11938 MockRead spdy_reads[] = {
11939 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11940 };
11941
11942 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11943 arraysize(spdy_writes));
11944 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11945
11946 TestCompletionCallback callback;
11947
11948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11949
tfarina42834112016-09-22 13:38:2011950 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911951 EXPECT_THAT(callback.GetResult(rv), IsOk());
11952
11953 const HttpResponseInfo* response = trans.GetResponseInfo();
11954 ASSERT_TRUE(response);
11955 ASSERT_TRUE(response->headers);
11956 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11957 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211958 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911959
11960 std::string response_data;
11961 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11962 EXPECT_EQ("hello!", response_data);
11963
11964 // Origin host bypasses proxy, no resolution should have happened.
11965 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11966}
11967
bncd16676a2016-07-20 16:23:0111968TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111969 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211970 proxy_config.set_auto_detect(true);
11971 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111972
sammc5dd160c2015-04-02 02:43:1311973 CapturingProxyResolver capturing_proxy_resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5911974 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1911975 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11976 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811977 &capturing_proxy_resolver),
11978 nullptr);
vishal.b62985ca92015-04-17 08:45:5111979 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711980 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111981
11982 HttpRequestInfo request;
11983 request.method = "GET";
bncb26024382016-06-29 02:39:4511984 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111985
11986 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211987 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311988 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211989 MockRead("\r\n"),
11990 MockRead("hello world"),
11991 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11992 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111993 };
11994
11995 StaticSocketDataProvider first_transaction(
11996 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711997 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511998 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611999 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512000 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112001
bnc032658ba2016-09-26 18:17:1512002 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112003
bncdf80d44fd2016-07-15 20:27:4112004 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512005 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112006 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312007 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512008 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12009 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312010 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112011 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112012 };
12013
[email protected]d911f1b2010-05-05 22:39:4212014 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12015
bnc42331402016-07-25 13:36:1512016 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112017 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112018 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112019 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12020 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112021 };
12022
rch8e6c6c42015-05-01 14:05:1312023 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12024 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712025 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112026
[email protected]d973e99a2012-02-17 21:02:3612027 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512028 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12029 NULL, 0, NULL, 0);
12030 hanging_non_alternate_protocol_socket.set_connect_data(
12031 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712032 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512033 &hanging_non_alternate_protocol_socket);
12034
[email protected]49639fa2011-12-20 23:22:4112035 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112036
danakj1fd259a02016-04-16 03:17:0912037 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812038 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912039 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112040
tfarina42834112016-09-22 13:38:2012041 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12043 EXPECT_THAT(callback.WaitForResult(), IsOk());
12044
12045 const HttpResponseInfo* response = trans->GetResponseInfo();
12046 ASSERT_TRUE(response);
12047 ASSERT_TRUE(response->headers);
12048 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12049 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212050 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112051
12052 std::string response_data;
12053 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12054 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112055
bnc87dcefc2017-05-25 12:47:5812056 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912057 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112058
tfarina42834112016-09-22 13:38:2012059 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12061 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112062
mmenkea2dcd3bf2016-08-16 21:49:4112063 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212064 ASSERT_TRUE(response);
12065 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212066 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312067 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212068 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112069
robpercival214763f2016-07-01 23:27:0112070 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112071 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512072 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12073 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312074 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312075 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312076 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112077
[email protected]029c83b62013-01-24 05:28:2012078 LoadTimingInfo load_timing_info;
12079 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12080 TestLoadTimingNotReusedWithPac(load_timing_info,
12081 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112082}
[email protected]631f1322010-04-30 17:59:1112083
bncd16676a2016-07-20 16:23:0112084TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812085 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412086 HttpRequestInfo request;
12087 request.method = "GET";
bncb26024382016-06-29 02:39:4512088 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5412089
12090 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212091 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312092 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212093 MockRead("\r\n"),
12094 MockRead("hello world"),
12095 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412096 };
12097
12098 StaticSocketDataProvider first_transaction(
12099 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712100 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512101 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612102 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512103 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412104
bnc032658ba2016-09-26 18:17:1512105 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412106
bncdf80d44fd2016-07-15 20:27:4112107 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512108 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112109 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412110
bnc42331402016-07-25 13:36:1512111 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112112 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412113 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112114 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412115 };
12116
rch8e6c6c42015-05-01 14:05:1312117 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12118 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712119 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412120
[email protected]83039bb2011-12-09 18:43:5512121 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412122
danakj1fd259a02016-04-16 03:17:0912123 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412124
bnc87dcefc2017-05-25 12:47:5812125 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912126 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412127
tfarina42834112016-09-22 13:38:2012128 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12130 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412131
12132 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212133 ASSERT_TRUE(response);
12134 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412135 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12136
12137 std::string response_data;
robpercival214763f2016-07-01 23:27:0112138 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412139 EXPECT_EQ("hello world", response_data);
12140
12141 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512142 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012143 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412144 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712145 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212146 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812147
bnc87dcefc2017-05-25 12:47:5812148 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912149 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412150
tfarina42834112016-09-22 13:38:2012151 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12153 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412154
12155 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212156 ASSERT_TRUE(response);
12157 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212158 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312159 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212160 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412161
robpercival214763f2016-07-01 23:27:0112162 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412163 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212164}
12165
[email protected]044de0642010-06-17 10:42:1512166// GenerateAuthToken is a mighty big test.
12167// It tests all permutation of GenerateAuthToken behavior:
12168// - Synchronous and Asynchronous completion.
12169// - OK or error on completion.
12170// - Direct connection, non-authenticating proxy, and authenticating proxy.
12171// - HTTP or HTTPS backend (to include proxy tunneling).
12172// - Non-authenticating and authenticating backend.
12173//
[email protected]fe3b7dc2012-02-03 19:52:0912174// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512175// problems generating an auth token for an authenticating proxy, we don't
12176// need to test all permutations of the backend server).
12177//
12178// The test proceeds by going over each of the configuration cases, and
12179// potentially running up to three rounds in each of the tests. The TestConfig
12180// specifies both the configuration for the test as well as the expectations
12181// for the results.
bncd16676a2016-07-20 16:23:0112182TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012183 static const char kServer[] = "http://www.example.com";
12184 static const char kSecureServer[] = "https://www.example.com";
12185 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512186
12187 enum AuthTiming {
12188 AUTH_NONE,
12189 AUTH_SYNC,
12190 AUTH_ASYNC,
12191 };
12192
12193 const MockWrite kGet(
12194 "GET / HTTP/1.1\r\n"
12195 "Host: www.example.com\r\n"
12196 "Connection: keep-alive\r\n\r\n");
12197 const MockWrite kGetProxy(
12198 "GET http://www.example.com/ HTTP/1.1\r\n"
12199 "Host: www.example.com\r\n"
12200 "Proxy-Connection: keep-alive\r\n\r\n");
12201 const MockWrite kGetAuth(
12202 "GET / HTTP/1.1\r\n"
12203 "Host: www.example.com\r\n"
12204 "Connection: keep-alive\r\n"
12205 "Authorization: auth_token\r\n\r\n");
12206 const MockWrite kGetProxyAuth(
12207 "GET http://www.example.com/ HTTP/1.1\r\n"
12208 "Host: www.example.com\r\n"
12209 "Proxy-Connection: keep-alive\r\n"
12210 "Proxy-Authorization: auth_token\r\n\r\n");
12211 const MockWrite kGetAuthThroughProxy(
12212 "GET http://www.example.com/ HTTP/1.1\r\n"
12213 "Host: www.example.com\r\n"
12214 "Proxy-Connection: keep-alive\r\n"
12215 "Authorization: auth_token\r\n\r\n");
12216 const MockWrite kGetAuthWithProxyAuth(
12217 "GET http://www.example.com/ HTTP/1.1\r\n"
12218 "Host: www.example.com\r\n"
12219 "Proxy-Connection: keep-alive\r\n"
12220 "Proxy-Authorization: auth_token\r\n"
12221 "Authorization: auth_token\r\n\r\n");
12222 const MockWrite kConnect(
12223 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712224 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512225 "Proxy-Connection: keep-alive\r\n\r\n");
12226 const MockWrite kConnectProxyAuth(
12227 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712228 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512229 "Proxy-Connection: keep-alive\r\n"
12230 "Proxy-Authorization: auth_token\r\n\r\n");
12231
12232 const MockRead kSuccess(
12233 "HTTP/1.1 200 OK\r\n"
12234 "Content-Type: text/html; charset=iso-8859-1\r\n"
12235 "Content-Length: 3\r\n\r\n"
12236 "Yes");
12237 const MockRead kFailure(
12238 "Should not be called.");
12239 const MockRead kServerChallenge(
12240 "HTTP/1.1 401 Unauthorized\r\n"
12241 "WWW-Authenticate: Mock realm=server\r\n"
12242 "Content-Type: text/html; charset=iso-8859-1\r\n"
12243 "Content-Length: 14\r\n\r\n"
12244 "Unauthorized\r\n");
12245 const MockRead kProxyChallenge(
12246 "HTTP/1.1 407 Unauthorized\r\n"
12247 "Proxy-Authenticate: Mock realm=proxy\r\n"
12248 "Proxy-Connection: close\r\n"
12249 "Content-Type: text/html; charset=iso-8859-1\r\n"
12250 "Content-Length: 14\r\n\r\n"
12251 "Unauthorized\r\n");
12252 const MockRead kProxyConnected(
12253 "HTTP/1.1 200 Connection Established\r\n\r\n");
12254
12255 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12256 // no constructors, but the C++ compiler on Windows warns about
12257 // unspecified data in compound literals. So, moved to using constructors,
12258 // and TestRound's created with the default constructor should not be used.
12259 struct TestRound {
12260 TestRound()
12261 : expected_rv(ERR_UNEXPECTED),
12262 extra_write(NULL),
12263 extra_read(NULL) {
12264 }
12265 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12266 int expected_rv_arg)
12267 : write(write_arg),
12268 read(read_arg),
12269 expected_rv(expected_rv_arg),
12270 extra_write(NULL),
12271 extra_read(NULL) {
12272 }
12273 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12274 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112275 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512276 : write(write_arg),
12277 read(read_arg),
12278 expected_rv(expected_rv_arg),
12279 extra_write(extra_write_arg),
12280 extra_read(extra_read_arg) {
12281 }
12282 MockWrite write;
12283 MockRead read;
12284 int expected_rv;
12285 const MockWrite* extra_write;
12286 const MockRead* extra_read;
12287 };
12288
12289 static const int kNoSSL = 500;
12290
12291 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112292 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112293 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512294 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112295 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112296 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512297 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112298 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512299 int num_auth_rounds;
12300 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612301 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512302 } test_configs[] = {
asankac93076192016-10-03 15:46:0212303 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112304 {__LINE__,
12305 nullptr,
asankac93076192016-10-03 15:46:0212306 AUTH_NONE,
12307 OK,
12308 kServer,
12309 AUTH_NONE,
12310 OK,
12311 1,
12312 kNoSSL,
12313 {TestRound(kGet, kSuccess, OK)}},
12314 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112315 {__LINE__,
12316 nullptr,
asankac93076192016-10-03 15:46:0212317 AUTH_NONE,
12318 OK,
12319 kServer,
12320 AUTH_SYNC,
12321 OK,
12322 2,
12323 kNoSSL,
12324 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512325 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112326 {__LINE__,
12327 nullptr,
asankac93076192016-10-03 15:46:0212328 AUTH_NONE,
12329 OK,
12330 kServer,
12331 AUTH_SYNC,
12332 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612333 3,
12334 kNoSSL,
12335 {TestRound(kGet, kServerChallenge, OK),
12336 TestRound(kGet, kServerChallenge, OK),
12337 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112338 {__LINE__,
12339 nullptr,
asankae2257db2016-10-11 22:03:1612340 AUTH_NONE,
12341 OK,
12342 kServer,
12343 AUTH_SYNC,
12344 ERR_UNSUPPORTED_AUTH_SCHEME,
12345 2,
12346 kNoSSL,
12347 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112348 {__LINE__,
12349 nullptr,
asankae2257db2016-10-11 22:03:1612350 AUTH_NONE,
12351 OK,
12352 kServer,
12353 AUTH_SYNC,
12354 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12355 2,
12356 kNoSSL,
12357 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112358 {__LINE__,
12359 kProxy,
asankae2257db2016-10-11 22:03:1612360 AUTH_SYNC,
12361 ERR_FAILED,
12362 kServer,
12363 AUTH_NONE,
12364 OK,
12365 2,
12366 kNoSSL,
12367 {TestRound(kGetProxy, kProxyChallenge, OK),
12368 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112369 {__LINE__,
12370 kProxy,
asankae2257db2016-10-11 22:03:1612371 AUTH_ASYNC,
12372 ERR_FAILED,
12373 kServer,
12374 AUTH_NONE,
12375 OK,
12376 2,
12377 kNoSSL,
12378 {TestRound(kGetProxy, kProxyChallenge, OK),
12379 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112380 {__LINE__,
12381 nullptr,
asankae2257db2016-10-11 22:03:1612382 AUTH_NONE,
12383 OK,
12384 kServer,
12385 AUTH_SYNC,
12386 ERR_FAILED,
asankac93076192016-10-03 15:46:0212387 2,
12388 kNoSSL,
12389 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612390 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112391 {__LINE__,
12392 nullptr,
asankae2257db2016-10-11 22:03:1612393 AUTH_NONE,
12394 OK,
12395 kServer,
12396 AUTH_ASYNC,
12397 ERR_FAILED,
12398 2,
12399 kNoSSL,
12400 {TestRound(kGet, kServerChallenge, OK),
12401 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112402 {__LINE__,
12403 nullptr,
asankac93076192016-10-03 15:46:0212404 AUTH_NONE,
12405 OK,
12406 kServer,
12407 AUTH_ASYNC,
12408 OK,
12409 2,
12410 kNoSSL,
12411 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512412 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112413 {__LINE__,
12414 nullptr,
asankac93076192016-10-03 15:46:0212415 AUTH_NONE,
12416 OK,
12417 kServer,
12418 AUTH_ASYNC,
12419 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612420 3,
asankac93076192016-10-03 15:46:0212421 kNoSSL,
12422 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612423 // The second round uses a HttpAuthHandlerMock that always succeeds.
12424 TestRound(kGet, kServerChallenge, OK),
12425 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212426 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112427 {__LINE__,
12428 kProxy,
asankac93076192016-10-03 15:46:0212429 AUTH_NONE,
12430 OK,
12431 kServer,
12432 AUTH_NONE,
12433 OK,
12434 1,
12435 kNoSSL,
12436 {TestRound(kGetProxy, kSuccess, OK)}},
12437 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112438 {__LINE__,
12439 kProxy,
asankac93076192016-10-03 15:46:0212440 AUTH_NONE,
12441 OK,
12442 kServer,
12443 AUTH_SYNC,
12444 OK,
12445 2,
12446 kNoSSL,
12447 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512448 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112449 {__LINE__,
12450 kProxy,
asankac93076192016-10-03 15:46:0212451 AUTH_NONE,
12452 OK,
12453 kServer,
12454 AUTH_SYNC,
12455 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612456 3,
asankac93076192016-10-03 15:46:0212457 kNoSSL,
12458 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612459 TestRound(kGetProxy, kServerChallenge, OK),
12460 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112461 {__LINE__,
12462 kProxy,
asankac93076192016-10-03 15:46:0212463 AUTH_NONE,
12464 OK,
12465 kServer,
12466 AUTH_ASYNC,
12467 OK,
12468 2,
12469 kNoSSL,
12470 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512471 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112472 {__LINE__,
12473 kProxy,
asankac93076192016-10-03 15:46:0212474 AUTH_NONE,
12475 OK,
12476 kServer,
12477 AUTH_ASYNC,
12478 ERR_INVALID_AUTH_CREDENTIALS,
12479 2,
12480 kNoSSL,
12481 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612482 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212483 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112484 {__LINE__,
12485 kProxy,
asankac93076192016-10-03 15:46:0212486 AUTH_SYNC,
12487 OK,
12488 kServer,
12489 AUTH_NONE,
12490 OK,
12491 2,
12492 kNoSSL,
12493 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512494 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112495 {__LINE__,
12496 kProxy,
asankac93076192016-10-03 15:46:0212497 AUTH_SYNC,
12498 ERR_INVALID_AUTH_CREDENTIALS,
12499 kServer,
12500 AUTH_NONE,
12501 OK,
12502 2,
12503 kNoSSL,
12504 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612505 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112506 {__LINE__,
12507 kProxy,
asankac93076192016-10-03 15:46:0212508 AUTH_ASYNC,
12509 OK,
12510 kServer,
12511 AUTH_NONE,
12512 OK,
12513 2,
12514 kNoSSL,
12515 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512516 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112517 {__LINE__,
12518 kProxy,
asankac93076192016-10-03 15:46:0212519 AUTH_ASYNC,
12520 ERR_INVALID_AUTH_CREDENTIALS,
12521 kServer,
12522 AUTH_NONE,
12523 OK,
12524 2,
12525 kNoSSL,
12526 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612527 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112528 {__LINE__,
12529 kProxy,
12530 AUTH_ASYNC,
12531 ERR_INVALID_AUTH_CREDENTIALS,
12532 kServer,
12533 AUTH_NONE,
12534 OK,
12535 3,
12536 kNoSSL,
12537 {TestRound(kGetProxy, kProxyChallenge, OK),
12538 TestRound(kGetProxy, kProxyChallenge, OK),
12539 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212540 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112541 {__LINE__,
12542 kProxy,
asankac93076192016-10-03 15:46:0212543 AUTH_SYNC,
12544 OK,
12545 kServer,
12546 AUTH_SYNC,
12547 OK,
12548 3,
12549 kNoSSL,
12550 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512551 TestRound(kGetProxyAuth, kServerChallenge, OK),
12552 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112553 {__LINE__,
12554 kProxy,
asankac93076192016-10-03 15:46:0212555 AUTH_SYNC,
12556 OK,
12557 kServer,
12558 AUTH_SYNC,
12559 ERR_INVALID_AUTH_CREDENTIALS,
12560 3,
12561 kNoSSL,
12562 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512563 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612564 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112565 {__LINE__,
12566 kProxy,
asankac93076192016-10-03 15:46:0212567 AUTH_ASYNC,
12568 OK,
12569 kServer,
12570 AUTH_SYNC,
12571 OK,
12572 3,
12573 kNoSSL,
12574 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512575 TestRound(kGetProxyAuth, kServerChallenge, OK),
12576 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112577 {__LINE__,
12578 kProxy,
asankac93076192016-10-03 15:46:0212579 AUTH_ASYNC,
12580 OK,
12581 kServer,
12582 AUTH_SYNC,
12583 ERR_INVALID_AUTH_CREDENTIALS,
12584 3,
12585 kNoSSL,
12586 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512587 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612588 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112589 {__LINE__,
12590 kProxy,
asankac93076192016-10-03 15:46:0212591 AUTH_SYNC,
12592 OK,
12593 kServer,
12594 AUTH_ASYNC,
12595 OK,
12596 3,
12597 kNoSSL,
12598 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512599 TestRound(kGetProxyAuth, kServerChallenge, OK),
12600 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112601 {__LINE__,
12602 kProxy,
12603 AUTH_SYNC,
12604 ERR_INVALID_AUTH_CREDENTIALS,
12605 kServer,
12606 AUTH_ASYNC,
12607 OK,
12608 4,
12609 kNoSSL,
12610 {TestRound(kGetProxy, kProxyChallenge, OK),
12611 TestRound(kGetProxy, kProxyChallenge, OK),
12612 TestRound(kGetProxyAuth, kServerChallenge, OK),
12613 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12614 {__LINE__,
12615 kProxy,
asankac93076192016-10-03 15:46:0212616 AUTH_SYNC,
12617 OK,
12618 kServer,
12619 AUTH_ASYNC,
12620 ERR_INVALID_AUTH_CREDENTIALS,
12621 3,
12622 kNoSSL,
12623 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512624 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612625 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112626 {__LINE__,
12627 kProxy,
asankac93076192016-10-03 15:46:0212628 AUTH_ASYNC,
12629 OK,
12630 kServer,
12631 AUTH_ASYNC,
12632 OK,
12633 3,
12634 kNoSSL,
12635 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512636 TestRound(kGetProxyAuth, kServerChallenge, OK),
12637 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112638 {__LINE__,
12639 kProxy,
asankac93076192016-10-03 15:46:0212640 AUTH_ASYNC,
12641 OK,
12642 kServer,
12643 AUTH_ASYNC,
12644 ERR_INVALID_AUTH_CREDENTIALS,
12645 3,
12646 kNoSSL,
12647 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512648 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612649 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112650 {__LINE__,
12651 kProxy,
12652 AUTH_ASYNC,
12653 ERR_INVALID_AUTH_CREDENTIALS,
12654 kServer,
12655 AUTH_ASYNC,
12656 ERR_INVALID_AUTH_CREDENTIALS,
12657 4,
12658 kNoSSL,
12659 {TestRound(kGetProxy, kProxyChallenge, OK),
12660 TestRound(kGetProxy, kProxyChallenge, OK),
12661 TestRound(kGetProxyAuth, kServerChallenge, OK),
12662 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212663 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112664 {__LINE__,
12665 nullptr,
asankac93076192016-10-03 15:46:0212666 AUTH_NONE,
12667 OK,
12668 kSecureServer,
12669 AUTH_NONE,
12670 OK,
12671 1,
12672 0,
12673 {TestRound(kGet, kSuccess, OK)}},
12674 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112675 {__LINE__,
12676 nullptr,
asankac93076192016-10-03 15:46:0212677 AUTH_NONE,
12678 OK,
12679 kSecureServer,
12680 AUTH_SYNC,
12681 OK,
12682 2,
12683 0,
12684 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512685 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112686 {__LINE__,
12687 nullptr,
asankac93076192016-10-03 15:46:0212688 AUTH_NONE,
12689 OK,
12690 kSecureServer,
12691 AUTH_SYNC,
12692 ERR_INVALID_AUTH_CREDENTIALS,
12693 2,
12694 0,
asankae2257db2016-10-11 22:03:1612695 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112696 {__LINE__,
12697 nullptr,
asankac93076192016-10-03 15:46:0212698 AUTH_NONE,
12699 OK,
12700 kSecureServer,
12701 AUTH_ASYNC,
12702 OK,
12703 2,
12704 0,
12705 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512706 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112707 {__LINE__,
12708 nullptr,
asankac93076192016-10-03 15:46:0212709 AUTH_NONE,
12710 OK,
12711 kSecureServer,
12712 AUTH_ASYNC,
12713 ERR_INVALID_AUTH_CREDENTIALS,
12714 2,
12715 0,
asankae2257db2016-10-11 22:03:1612716 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212717 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112718 {__LINE__,
12719 kProxy,
asankac93076192016-10-03 15:46:0212720 AUTH_NONE,
12721 OK,
12722 kSecureServer,
12723 AUTH_NONE,
12724 OK,
12725 1,
12726 0,
12727 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12728 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112729 {__LINE__,
12730 kProxy,
asankac93076192016-10-03 15:46:0212731 AUTH_NONE,
12732 OK,
12733 kSecureServer,
12734 AUTH_SYNC,
12735 OK,
12736 2,
12737 0,
12738 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512739 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112740 {__LINE__,
12741 kProxy,
asankac93076192016-10-03 15:46:0212742 AUTH_NONE,
12743 OK,
12744 kSecureServer,
12745 AUTH_SYNC,
12746 ERR_INVALID_AUTH_CREDENTIALS,
12747 2,
12748 0,
12749 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612750 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112751 {__LINE__,
12752 kProxy,
asankac93076192016-10-03 15:46:0212753 AUTH_NONE,
12754 OK,
12755 kSecureServer,
12756 AUTH_ASYNC,
12757 OK,
12758 2,
12759 0,
12760 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512761 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112762 {__LINE__,
12763 kProxy,
asankac93076192016-10-03 15:46:0212764 AUTH_NONE,
12765 OK,
12766 kSecureServer,
12767 AUTH_ASYNC,
12768 ERR_INVALID_AUTH_CREDENTIALS,
12769 2,
12770 0,
12771 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612772 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212773 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112774 {__LINE__,
12775 kProxy,
asankac93076192016-10-03 15:46:0212776 AUTH_SYNC,
12777 OK,
12778 kSecureServer,
12779 AUTH_NONE,
12780 OK,
12781 2,
12782 1,
12783 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512784 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112785 {__LINE__,
12786 kProxy,
asankac93076192016-10-03 15:46:0212787 AUTH_SYNC,
12788 ERR_INVALID_AUTH_CREDENTIALS,
12789 kSecureServer,
12790 AUTH_NONE,
12791 OK,
12792 2,
12793 kNoSSL,
12794 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612795 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112796 {__LINE__,
12797 kProxy,
asankae2257db2016-10-11 22:03:1612798 AUTH_SYNC,
12799 ERR_UNSUPPORTED_AUTH_SCHEME,
12800 kSecureServer,
12801 AUTH_NONE,
12802 OK,
12803 2,
12804 kNoSSL,
12805 {TestRound(kConnect, kProxyChallenge, OK),
12806 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112807 {__LINE__,
12808 kProxy,
asankae2257db2016-10-11 22:03:1612809 AUTH_SYNC,
12810 ERR_UNEXPECTED,
12811 kSecureServer,
12812 AUTH_NONE,
12813 OK,
12814 2,
12815 kNoSSL,
12816 {TestRound(kConnect, kProxyChallenge, OK),
12817 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112818 {__LINE__,
12819 kProxy,
asankac93076192016-10-03 15:46:0212820 AUTH_ASYNC,
12821 OK,
12822 kSecureServer,
12823 AUTH_NONE,
12824 OK,
12825 2,
12826 1,
12827 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512828 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112829 {__LINE__,
12830 kProxy,
asankac93076192016-10-03 15:46:0212831 AUTH_ASYNC,
12832 ERR_INVALID_AUTH_CREDENTIALS,
12833 kSecureServer,
12834 AUTH_NONE,
12835 OK,
12836 2,
12837 kNoSSL,
12838 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612839 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212840 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112841 {__LINE__,
12842 kProxy,
asankac93076192016-10-03 15:46:0212843 AUTH_SYNC,
12844 OK,
12845 kSecureServer,
12846 AUTH_SYNC,
12847 OK,
12848 3,
12849 1,
12850 {TestRound(kConnect, kProxyChallenge, OK),
12851 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12852 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512853 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112854 {__LINE__,
12855 kProxy,
asankac93076192016-10-03 15:46:0212856 AUTH_SYNC,
12857 OK,
12858 kSecureServer,
12859 AUTH_SYNC,
12860 ERR_INVALID_AUTH_CREDENTIALS,
12861 3,
12862 1,
12863 {TestRound(kConnect, kProxyChallenge, OK),
12864 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12865 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612866 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112867 {__LINE__,
12868 kProxy,
asankac93076192016-10-03 15:46:0212869 AUTH_ASYNC,
12870 OK,
12871 kSecureServer,
12872 AUTH_SYNC,
12873 OK,
12874 3,
12875 1,
12876 {TestRound(kConnect, kProxyChallenge, OK),
12877 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12878 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512879 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112880 {__LINE__,
12881 kProxy,
asankac93076192016-10-03 15:46:0212882 AUTH_ASYNC,
12883 OK,
12884 kSecureServer,
12885 AUTH_SYNC,
12886 ERR_INVALID_AUTH_CREDENTIALS,
12887 3,
12888 1,
12889 {TestRound(kConnect, kProxyChallenge, OK),
12890 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12891 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612892 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112893 {__LINE__,
12894 kProxy,
asankac93076192016-10-03 15:46:0212895 AUTH_SYNC,
12896 OK,
12897 kSecureServer,
12898 AUTH_ASYNC,
12899 OK,
12900 3,
12901 1,
12902 {TestRound(kConnect, kProxyChallenge, OK),
12903 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12904 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512905 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112906 {__LINE__,
12907 kProxy,
asankac93076192016-10-03 15:46:0212908 AUTH_SYNC,
12909 OK,
12910 kSecureServer,
12911 AUTH_ASYNC,
12912 ERR_INVALID_AUTH_CREDENTIALS,
12913 3,
12914 1,
12915 {TestRound(kConnect, kProxyChallenge, OK),
12916 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12917 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612918 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112919 {__LINE__,
12920 kProxy,
asankac93076192016-10-03 15:46:0212921 AUTH_ASYNC,
12922 OK,
12923 kSecureServer,
12924 AUTH_ASYNC,
12925 OK,
12926 3,
12927 1,
12928 {TestRound(kConnect, kProxyChallenge, OK),
12929 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12930 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512931 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112932 {__LINE__,
12933 kProxy,
asankac93076192016-10-03 15:46:0212934 AUTH_ASYNC,
12935 OK,
12936 kSecureServer,
12937 AUTH_ASYNC,
12938 ERR_INVALID_AUTH_CREDENTIALS,
12939 3,
12940 1,
12941 {TestRound(kConnect, kProxyChallenge, OK),
12942 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12943 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612944 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112945 {__LINE__,
12946 kProxy,
12947 AUTH_ASYNC,
12948 ERR_INVALID_AUTH_CREDENTIALS,
12949 kSecureServer,
12950 AUTH_ASYNC,
12951 ERR_INVALID_AUTH_CREDENTIALS,
12952 4,
12953 2,
12954 {TestRound(kConnect, kProxyChallenge, OK),
12955 TestRound(kConnect, kProxyChallenge, OK),
12956 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12957 &kServerChallenge),
12958 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512959 };
12960
asanka463ca4262016-11-16 02:34:3112961 for (const auto& test_config : test_configs) {
12962 SCOPED_TRACE(::testing::Message() << "Test config at "
12963 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812964 HttpAuthHandlerMock::Factory* auth_factory(
12965 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712966 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912967 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612968
12969 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512970 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112971 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812972 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12973 std::string auth_challenge = "Mock realm=proxy";
12974 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412975 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12976 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812977 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012978 empty_ssl_info, origin,
12979 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812980 auth_handler->SetGenerateExpectation(
12981 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112982 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812983 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12984 }
[email protected]044de0642010-06-17 10:42:1512985 }
12986 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012987 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512988 std::string auth_challenge = "Mock realm=server";
12989 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412990 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12991 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512992 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012993 empty_ssl_info, origin,
12994 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512995 auth_handler->SetGenerateExpectation(
12996 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112997 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812998 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612999
13000 // The second handler always succeeds. It should only be used where there
13001 // are multiple auth sessions for server auth in the same network
13002 // transaction using the same auth scheme.
13003 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913004 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613005 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13006 empty_ssl_info, origin,
13007 NetLogWithSource());
13008 second_handler->SetGenerateExpectation(true, OK);
13009 auth_factory->AddMockHandler(second_handler.release(),
13010 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513011 }
13012 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913013 session_deps_.proxy_resolution_service =
13014 ProxyResolutionService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1513015 } else {
Lily Houghton8c2f97d2018-01-22 05:06:5913016 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513017 }
13018
13019 HttpRequestInfo request;
13020 request.method = "GET";
13021 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1513022
danakj1fd259a02016-04-16 03:17:0913023 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513024
rchcb68dc62015-05-21 04:45:3613025 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13026
13027 std::vector<std::vector<MockRead>> mock_reads(1);
13028 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513029 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213030 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513031 const TestRound& read_write_round = test_config.rounds[round];
13032
13033 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613034 mock_reads.back().push_back(read_write_round.read);
13035 mock_writes.back().push_back(read_write_round.write);
13036
13037 // kProxyChallenge uses Proxy-Connection: close which means that the
13038 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413039 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613040 mock_reads.push_back(std::vector<MockRead>());
13041 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513042 }
13043
rchcb68dc62015-05-21 04:45:3613044 if (read_write_round.extra_read) {
13045 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513046 }
rchcb68dc62015-05-21 04:45:3613047 if (read_write_round.extra_write) {
13048 mock_writes.back().push_back(*read_write_round.extra_write);
13049 }
[email protected]044de0642010-06-17 10:42:1513050
13051 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513052 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713053 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513054 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613055 }
[email protected]044de0642010-06-17 10:42:1513056
danakj1fd259a02016-04-16 03:17:0913057 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613058 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913059 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5413060 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5813061 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3613062 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213063 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613064 }
13065
mmenkecc2298e2015-12-07 18:20:1813066 // Transaction must be created after DataProviders, so it's destroyed before
13067 // they are as well.
13068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13069
rchcb68dc62015-05-21 04:45:3613070 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213071 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613072 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513073 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113074 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513075 int rv;
13076 if (round == 0) {
tfarina42834112016-09-22 13:38:2013077 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513078 } else {
[email protected]49639fa2011-12-20 23:22:4113079 rv = trans.RestartWithAuth(
13080 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513081 }
13082 if (rv == ERR_IO_PENDING)
13083 rv = callback.WaitForResult();
13084
13085 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613086 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013087 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513088 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513089 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13090 continue;
13091 }
13092 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213093 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513094 } else {
wezca1070932016-05-26 20:30:5213095 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613096 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513097 }
13098 }
[email protected]e5ae96a2010-04-14 20:12:4513099 }
13100}
13101
bncd16676a2016-07-20 16:23:0113102TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413103 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413104 HttpAuthHandlerMock::Factory* auth_factory(
13105 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713106 session_deps_.http_auth_handler_factory.reset(auth_factory);
Lily Houghton8c2f97d2018-01-22 05:06:5913107 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713108 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13109 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413110
13111 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13112 auth_handler->set_connection_based(true);
13113 std::string auth_challenge = "Mock realm=server";
13114 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413115 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13116 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913117 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413118 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013119 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813120 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413121
[email protected]c871bce92010-07-15 21:51:1413122 int rv = OK;
13123 const HttpResponseInfo* response = NULL;
13124 HttpRequestInfo request;
13125 request.method = "GET";
13126 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2713127
danakj1fd259a02016-04-16 03:17:0913128 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013129
13130 // Use a TCP Socket Pool with only one connection per group. This is used
13131 // to validate that the TCP socket is not released to the pool between
13132 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213133 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813134 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013135 50, // Max sockets for pool
13136 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113137 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13138 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913139 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213140 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813141 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013142
bnc691fda62016-08-12 00:43:1613143 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113144 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413145
13146 const MockWrite kGet(
13147 "GET / HTTP/1.1\r\n"
13148 "Host: www.example.com\r\n"
13149 "Connection: keep-alive\r\n\r\n");
13150 const MockWrite kGetAuth(
13151 "GET / HTTP/1.1\r\n"
13152 "Host: www.example.com\r\n"
13153 "Connection: keep-alive\r\n"
13154 "Authorization: auth_token\r\n\r\n");
13155
13156 const MockRead kServerChallenge(
13157 "HTTP/1.1 401 Unauthorized\r\n"
13158 "WWW-Authenticate: Mock realm=server\r\n"
13159 "Content-Type: text/html; charset=iso-8859-1\r\n"
13160 "Content-Length: 14\r\n\r\n"
13161 "Unauthorized\r\n");
13162 const MockRead kSuccess(
13163 "HTTP/1.1 200 OK\r\n"
13164 "Content-Type: text/html; charset=iso-8859-1\r\n"
13165 "Content-Length: 3\r\n\r\n"
13166 "Yes");
13167
13168 MockWrite writes[] = {
13169 // First round
13170 kGet,
13171 // Second round
13172 kGetAuth,
13173 // Third round
13174 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013175 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013176 kGetAuth,
13177 // Competing request
13178 kGet,
[email protected]c871bce92010-07-15 21:51:1413179 };
13180 MockRead reads[] = {
13181 // First round
13182 kServerChallenge,
13183 // Second round
13184 kServerChallenge,
13185 // Third round
[email protected]eca50e122010-09-11 14:03:3013186 kServerChallenge,
13187 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413188 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013189 // Competing response
13190 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413191 };
13192 StaticSocketDataProvider data_provider(reads, arraysize(reads),
13193 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0713194 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413195
thestig9d3bb0c2015-01-24 00:49:5113196 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013197
13198 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413199 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013200 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413201 if (rv == ERR_IO_PENDING)
13202 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113203 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613204 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213205 ASSERT_TRUE(response);
13206 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813207 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113208 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13209 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413210
[email protected]7ef4cbbb2011-02-06 11:19:1013211 // In between rounds, another request comes in for the same domain.
13212 // It should not be able to grab the TCP socket that trans has already
13213 // claimed.
bnc691fda62016-08-12 00:43:1613214 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113215 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013216 rv = trans_compete.Start(&request, callback_compete.callback(),
13217 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013219 // callback_compete.WaitForResult at this point would stall forever,
13220 // since the HttpNetworkTransaction does not release the request back to
13221 // the pool until after authentication completes.
13222
13223 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413224 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613225 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413226 if (rv == ERR_IO_PENDING)
13227 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113228 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613229 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213230 ASSERT_TRUE(response);
13231 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813232 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113233 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13234 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413235
[email protected]7ef4cbbb2011-02-06 11:19:1013236 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413237 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613238 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413239 if (rv == ERR_IO_PENDING)
13240 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113241 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613242 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213243 ASSERT_TRUE(response);
13244 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813245 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113246 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13247 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013248
[email protected]7ef4cbbb2011-02-06 11:19:1013249 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013250 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613251 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013252 if (rv == ERR_IO_PENDING)
13253 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113254 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613255 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213256 ASSERT_TRUE(response);
13257 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813258 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013259
asanka463ca4262016-11-16 02:34:3113260 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13261 // auth handler should transition to a DONE state in concert with the remote
13262 // server. But that's not something we can test here with a mock handler.
13263 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13264 auth_handler->state());
13265
[email protected]7ef4cbbb2011-02-06 11:19:1013266 // Read the body since the fourth round was successful. This will also
13267 // release the socket back to the pool.
13268 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613269 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013270 if (rv == ERR_IO_PENDING)
13271 rv = callback.WaitForResult();
13272 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613273 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013274 EXPECT_EQ(0, rv);
13275 // There are still 0 idle sockets, since the trans_compete transaction
13276 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813277 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013278
13279 // The competing request can now finish. Wait for the headers and then
13280 // read the body.
13281 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113282 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613283 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013284 if (rv == ERR_IO_PENDING)
13285 rv = callback.WaitForResult();
13286 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613287 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013288 EXPECT_EQ(0, rv);
13289
13290 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813291 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413292}
13293
[email protected]65041fa2010-05-21 06:56:5313294// This tests the case that a request is issued via http instead of spdy after
13295// npn is negotiated.
bncd16676a2016-07-20 16:23:0113296TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313297 HttpRequestInfo request;
13298 request.method = "GET";
bncce36dca22015-04-21 22:11:2313299 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5313300
13301 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313302 MockWrite(
13303 "GET / HTTP/1.1\r\n"
13304 "Host: www.example.org\r\n"
13305 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313306 };
13307
13308 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213309 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313310 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213311 MockRead("\r\n"),
13312 MockRead("hello world"),
13313 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313314 };
13315
[email protected]8ddf8322012-02-23 18:08:0613316 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613317 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313318
[email protected]bb88e1d32013-05-03 23:11:0713319 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313320
13321 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13322 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713323 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313324
[email protected]49639fa2011-12-20 23:22:4113325 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313326
danakj1fd259a02016-04-16 03:17:0913327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613328 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313329
tfarina42834112016-09-22 13:38:2013330 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313331
robpercival214763f2016-07-01 23:27:0113332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13333 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313334
bnc691fda62016-08-12 00:43:1613335 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213336 ASSERT_TRUE(response);
13337 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313338 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13339
13340 std::string response_data;
bnc691fda62016-08-12 00:43:1613341 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313342 EXPECT_EQ("hello world", response_data);
13343
13344 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213345 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313346}
[email protected]26ef6582010-06-24 02:30:4713347
bnc55ff9da2015-08-19 18:42:3513348// Simulate the SSL handshake completing with an NPN negotiation followed by an
13349// immediate server closing of the socket.
13350// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113351TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713352 HttpRequestInfo request;
13353 request.method = "GET";
bncce36dca22015-04-21 22:11:2313354 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4713355
[email protected]8ddf8322012-02-23 18:08:0613356 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613357 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713359
bncdf80d44fd2016-07-15 20:27:4113360 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913361 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4113362 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713363
13364 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613365 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713366 };
13367
rch8e6c6c42015-05-01 14:05:1313368 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13369 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713370 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713371
[email protected]49639fa2011-12-20 23:22:4113372 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713373
danakj1fd259a02016-04-16 03:17:0913374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713376
tfarina42834112016-09-22 13:38:2013377 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113378 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13379 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713380}
[email protected]65d34382010-07-01 18:12:2613381
[email protected]795cbf82013-07-22 09:37:2713382// A subclass of HttpAuthHandlerMock that records the request URL when
13383// it gets it. This is needed since the auth handler may get destroyed
13384// before we get a chance to query it.
13385class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13386 public:
13387 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13388
Chris Watkins7a41d3552017-12-01 02:13:2713389 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713390
13391 protected:
dchengb03027d2014-10-21 12:00:2013392 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13393 const HttpRequestInfo* request,
13394 const CompletionCallback& callback,
13395 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713396 *url_ = request->url;
13397 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13398 credentials, request, callback, auth_token);
13399 }
13400
13401 private:
13402 GURL* url_;
13403};
13404
[email protected]8e6441ca2010-08-19 05:56:3813405// Test that if we cancel the transaction as the connection is completing, that
13406// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113407TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813408 // Setup everything about the connection to complete synchronously, so that
13409 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13410 // for is the callback from the HttpStreamRequest.
13411 // Then cancel the transaction.
13412 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613413 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813414 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613415 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13416 MockRead(SYNCHRONOUS, "hello world"),
13417 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813418 };
13419
[email protected]8e6441ca2010-08-19 05:56:3813420 HttpRequestInfo request;
13421 request.method = "GET";
bncce36dca22015-04-21 22:11:2313422 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3813423
[email protected]bb88e1d32013-05-03 23:11:0713424 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813426 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913427 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713428
[email protected]8e6441ca2010-08-19 05:56:3813429 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13430 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713431 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813432
[email protected]49639fa2011-12-20 23:22:4113433 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813434
vishal.b62985ca92015-04-17 08:45:5113435 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113436 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113437 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813438 trans.reset(); // Cancel the transaction here.
13439
fdoray92e35a72016-06-10 15:54:5513440 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013441}
13442
[email protected]ecab6e052014-05-16 14:58:1213443// Test that if a transaction is cancelled after receiving the headers, the
13444// stream is drained properly and added back to the socket pool. The main
13445// purpose of this test is to make sure that an HttpStreamParser can be read
13446// from after the HttpNetworkTransaction and the objects it owns have been
13447// deleted.
13448// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113449TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213450 MockRead data_reads[] = {
13451 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13452 MockRead(ASYNC, "Content-Length: 2\r\n"),
13453 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13454 MockRead(ASYNC, "1"),
13455 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13456 // HttpNetworkTransaction has been deleted.
13457 MockRead(ASYNC, "2"),
13458 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13459 };
13460 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13461 session_deps_.socket_factory->AddSocketDataProvider(&data);
13462
danakj1fd259a02016-04-16 03:17:0913463 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213464
13465 {
13466 HttpRequestInfo request;
13467 request.method = "GET";
bncce36dca22015-04-21 22:11:2313468 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1213469
dcheng48459ac22014-08-26 00:46:4113470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213471 TestCompletionCallback callback;
13472
tfarina42834112016-09-22 13:38:2013473 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213475 callback.WaitForResult();
13476
13477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213478 ASSERT_TRUE(response);
13479 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213480 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13481
13482 // The transaction and HttpRequestInfo are deleted.
13483 }
13484
13485 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513486 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213487
13488 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113489 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213490}
13491
[email protected]76a505b2010-08-25 06:23:0013492// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113493TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913494 session_deps_.proxy_resolution_service =
13495 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113496 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713497 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013499
[email protected]76a505b2010-08-25 06:23:0013500 HttpRequestInfo request;
13501 request.method = "GET";
bncce36dca22015-04-21 22:11:2313502 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013503
13504 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313505 MockWrite(
13506 "GET http://www.example.org/ HTTP/1.1\r\n"
13507 "Host: www.example.org\r\n"
13508 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013509 };
13510
13511 MockRead data_reads1[] = {
13512 MockRead("HTTP/1.1 200 OK\r\n"),
13513 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13514 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613515 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013516 };
13517
13518 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13519 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713520 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013521
[email protected]49639fa2011-12-20 23:22:4113522 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013523
bnc691fda62016-08-12 00:43:1613524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913525 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613526 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913527 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13528 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013529
bnc691fda62016-08-12 00:43:1613530 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013532
13533 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113534 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013535
bnc691fda62016-08-12 00:43:1613536 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213537 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013538
13539 EXPECT_TRUE(response->headers->IsKeepAlive());
13540 EXPECT_EQ(200, response->headers->response_code());
13541 EXPECT_EQ(100, response->headers->GetContentLength());
13542 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713543 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13544 HostPortPair::FromString("myproxy:70")),
13545 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913546 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13547 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13548 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013549 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013550
13551 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613552 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013553 TestLoadTimingNotReusedWithPac(load_timing_info,
13554 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013555}
13556
13557// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113558TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913559 session_deps_.proxy_resolution_service =
13560 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113561 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713562 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913563 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013564
[email protected]76a505b2010-08-25 06:23:0013565 HttpRequestInfo request;
13566 request.method = "GET";
bncce36dca22015-04-21 22:11:2313567 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013568
13569 // Since we have proxy, should try to establish tunnel.
13570 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713571 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13572 "Host: www.example.org:443\r\n"
13573 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013574
rsleevidb16bb02015-11-12 23:47:1713575 MockWrite("GET / HTTP/1.1\r\n"
13576 "Host: www.example.org\r\n"
13577 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013578 };
13579
13580 MockRead data_reads1[] = {
13581 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13582
13583 MockRead("HTTP/1.1 200 OK\r\n"),
13584 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13585 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613586 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013587 };
13588
13589 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13590 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713591 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613592 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013594
[email protected]49639fa2011-12-20 23:22:4113595 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013596
bnc691fda62016-08-12 00:43:1613597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913598 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613599 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913600 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13601 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013602
bnc691fda62016-08-12 00:43:1613603 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013605
13606 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113607 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613608 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013609 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013610 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013611 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13612 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013613 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013614 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013615 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13616 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013617
bnc691fda62016-08-12 00:43:1613618 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213619 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013620
13621 EXPECT_TRUE(response->headers->IsKeepAlive());
13622 EXPECT_EQ(200, response->headers->response_code());
13623 EXPECT_EQ(100, response->headers->GetContentLength());
13624 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13625 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713626 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13627 HostPortPair::FromString("myproxy:70")),
13628 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913629 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13630 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13631 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013632
13633 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613634 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013635 TestLoadTimingNotReusedWithPac(load_timing_info,
13636 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013637}
13638
rsleevidb16bb02015-11-12 23:47:1713639// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13640// literal host.
bncd16676a2016-07-20 16:23:0113641TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913642 session_deps_.proxy_resolution_service =
13643 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
rsleevidb16bb02015-11-12 23:47:1713644 BoundTestNetLog log;
13645 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713647
13648 HttpRequestInfo request;
13649 request.method = "GET";
13650 request.url = GURL("https://[::1]:443/");
13651
13652 // Since we have proxy, should try to establish tunnel.
13653 MockWrite data_writes1[] = {
13654 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13655 "Host: [::1]:443\r\n"
13656 "Proxy-Connection: keep-alive\r\n\r\n"),
13657
13658 MockWrite("GET / HTTP/1.1\r\n"
13659 "Host: [::1]\r\n"
13660 "Connection: keep-alive\r\n\r\n"),
13661 };
13662
13663 MockRead data_reads1[] = {
13664 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13665
13666 MockRead("HTTP/1.1 200 OK\r\n"),
13667 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13668 MockRead("Content-Length: 100\r\n\r\n"),
13669 MockRead(SYNCHRONOUS, OK),
13670 };
13671
13672 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13673 data_writes1, arraysize(data_writes1));
13674 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13675 SSLSocketDataProvider ssl(ASYNC, OK);
13676 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13677
13678 TestCompletionCallback callback1;
13679
bnc691fda62016-08-12 00:43:1613680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713681
bnc691fda62016-08-12 00:43:1613682 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113683 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713684
13685 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113686 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713687 TestNetLogEntry::List entries;
13688 log.GetEntries(&entries);
13689 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013690 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13691 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713692 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013693 entries, pos,
13694 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13695 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713696
bnc691fda62016-08-12 00:43:1613697 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213698 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713699
13700 EXPECT_TRUE(response->headers->IsKeepAlive());
13701 EXPECT_EQ(200, response->headers->response_code());
13702 EXPECT_EQ(100, response->headers->GetContentLength());
13703 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13704 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713705 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13706 HostPortPair::FromString("myproxy:70")),
13707 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713708
13709 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613710 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713711 TestLoadTimingNotReusedWithPac(load_timing_info,
13712 CONNECT_TIMING_HAS_SSL_TIMES);
13713}
13714
[email protected]76a505b2010-08-25 06:23:0013715// Test a basic HTTPS GET request through a proxy, but the server hangs up
13716// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113717TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Lily Houghton8c2f97d2018-01-22 05:06:5913718 session_deps_.proxy_resolution_service =
13719 ProxyResolutionService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113720 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713721 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913722 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013723
[email protected]76a505b2010-08-25 06:23:0013724 HttpRequestInfo request;
13725 request.method = "GET";
bncce36dca22015-04-21 22:11:2313726 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013727
13728 // Since we have proxy, should try to establish tunnel.
13729 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713730 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13731 "Host: www.example.org:443\r\n"
13732 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013733
rsleevidb16bb02015-11-12 23:47:1713734 MockWrite("GET / HTTP/1.1\r\n"
13735 "Host: www.example.org\r\n"
13736 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013737 };
13738
13739 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0013740 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613741 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013742 };
13743
13744 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13745 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713746 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613747 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713748 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013749
[email protected]49639fa2011-12-20 23:22:4113750 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013751
bnc691fda62016-08-12 00:43:1613752 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013753
bnc691fda62016-08-12 00:43:1613754 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013756
13757 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113758 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613759 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013760 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013761 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013762 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13763 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013764 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013765 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013766 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13767 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013768}
13769
[email protected]749eefa82010-09-13 22:14:0313770// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113771TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113772 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913773 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113774 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313775
bnc42331402016-07-25 13:36:1513776 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113777 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313778 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113779 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313780 };
13781
rch8e6c6c42015-05-01 14:05:1313782 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13783 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713784 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313785
[email protected]8ddf8322012-02-23 18:08:0613786 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613787 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713788 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313789
danakj1fd259a02016-04-16 03:17:0913790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313791
13792 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313793 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013794 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0413795 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713796 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213797 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313798
13799 HttpRequestInfo request;
13800 request.method = "GET";
bncce36dca22015-04-21 22:11:2313801 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313802
13803 // This is the important line that marks this as a preconnect.
13804 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13805
bnc691fda62016-08-12 00:43:1613806 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313807
[email protected]41d64e82013-07-03 22:44:2613808 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013809 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13811 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313812}
13813
[email protected]73b8dd222010-11-11 19:55:2413814// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613815// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213816void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713817 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913818 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713819 request_info.url = GURL("https://www.example.com/");
13820 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913821 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713822
[email protected]8ddf8322012-02-23 18:08:0613823 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913824 MockWrite data_writes[] = {
13825 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413826 };
ttuttle859dc7a2015-04-23 19:42:2913827 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713828 session_deps_.socket_factory->AddSocketDataProvider(&data);
13829 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413830
danakj1fd259a02016-04-16 03:17:0913831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413833
[email protected]49639fa2011-12-20 23:22:4113834 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013835 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913836 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413837 rv = callback.WaitForResult();
13838 ASSERT_EQ(error, rv);
13839}
13840
bncd16676a2016-07-20 16:23:0113841TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413842 // Just check a grab bag of cert errors.
13843 static const int kErrors[] = {
13844 ERR_CERT_COMMON_NAME_INVALID,
13845 ERR_CERT_AUTHORITY_INVALID,
13846 ERR_CERT_DATE_INVALID,
13847 };
13848 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613849 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13850 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413851 }
13852}
13853
[email protected]bd0b6772011-01-11 19:59:3013854// Ensure that a client certificate is removed from the SSL client auth
13855// cache when:
13856// 1) No proxy is involved.
13857// 2) TLS False Start is disabled.
13858// 3) The initial TLS handshake requests a client certificate.
13859// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113860TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913861 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713862 request_info.url = GURL("https://www.example.com/");
13863 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913864 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713865
[email protected]bd0b6772011-01-11 19:59:3013866 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113867 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013868
13869 // [ssl_]data1 contains the data for the first SSL handshake. When a
13870 // CertificateRequest is received for the first time, the handshake will
13871 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913872 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013873 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913875 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713876 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013877
13878 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13879 // False Start is not being used, the result of the SSL handshake will be
13880 // returned as part of the SSLClientSocket::Connect() call. This test
13881 // matches the result of a server sending a handshake_failure alert,
13882 // rather than a Finished message, because it requires a client
13883 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913884 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013885 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713886 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913887 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713888 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013889
13890 // [ssl_]data3 contains the data for the third SSL handshake. When a
13891 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213892 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13893 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013894 // of the HttpNetworkTransaction. Because this test failure is due to
13895 // requiring a client certificate, this fallback handshake should also
13896 // fail.
ttuttle859dc7a2015-04-23 19:42:2913897 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013898 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713899 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913900 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713901 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013902
[email protected]80c75f682012-05-26 16:22:1713903 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13904 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213905 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13906 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713907 // of the HttpNetworkTransaction. Because this test failure is due to
13908 // requiring a client certificate, this fallback handshake should also
13909 // fail.
ttuttle859dc7a2015-04-23 19:42:2913910 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713911 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713912 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913913 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713914 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713915
danakj1fd259a02016-04-16 03:17:0913916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013918
[email protected]bd0b6772011-01-11 19:59:3013919 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113920 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013921 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113922 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013923
13924 // Complete the SSL handshake, which should abort due to requiring a
13925 // client certificate.
13926 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113927 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013928
13929 // Indicate that no certificate should be supplied. From the perspective
13930 // of SSLClientCertCache, NULL is just as meaningful as a real
13931 // certificate, so this is the same as supply a
13932 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613933 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113934 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013935
13936 // Ensure the certificate was added to the client auth cache before
13937 // allowing the connection to continue restarting.
13938 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413939 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113940 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413941 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213942 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013943
13944 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713945 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13946 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013947 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113948 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013949
13950 // Ensure that the client certificate is removed from the cache on a
13951 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113952 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413953 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013954}
13955
13956// Ensure that a client certificate is removed from the SSL client auth
13957// cache when:
13958// 1) No proxy is involved.
13959// 2) TLS False Start is enabled.
13960// 3) The initial TLS handshake requests a client certificate.
13961// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113962TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913963 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713964 request_info.url = GURL("https://www.example.com/");
13965 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913966 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713967
[email protected]bd0b6772011-01-11 19:59:3013968 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113969 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013970
13971 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13972 // return successfully after reading up to the peer's Certificate message.
13973 // This is to allow the caller to call SSLClientSocket::Write(), which can
13974 // enqueue application data to be sent in the same packet as the
13975 // ChangeCipherSpec and Finished messages.
13976 // The actual handshake will be finished when SSLClientSocket::Read() is
13977 // called, which expects to process the peer's ChangeCipherSpec and
13978 // Finished messages. If there was an error negotiating with the peer,
13979 // such as due to the peer requiring a client certificate when none was
13980 // supplied, the alert sent by the peer won't be processed until Read() is
13981 // called.
13982
13983 // Like the non-False Start case, when a client certificate is requested by
13984 // the peer, the handshake is aborted during the Connect() call.
13985 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913986 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013987 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913989 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713990 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013991
13992 // When a client certificate is supplied, Connect() will not be aborted
13993 // when the peer requests the certificate. Instead, the handshake will
13994 // artificially succeed, allowing the caller to write the HTTP request to
13995 // the socket. The handshake messages are not processed until Read() is
13996 // called, which then detects that the handshake was aborted, due to the
13997 // peer sending a handshake_failure because it requires a client
13998 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913999 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014000 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914002 MockRead data2_reads[] = {
14003 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014004 };
ttuttle859dc7a2015-04-23 19:42:2914005 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714006 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014007
14008 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714009 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14010 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914011 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014012 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714013 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914014 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714015 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014016
[email protected]80c75f682012-05-26 16:22:1714017 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14018 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914019 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714020 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714021 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2914022 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714023 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714024
[email protected]7799de12013-05-30 05:52:5114025 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914026 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114027 ssl_data5.cert_request_info = cert_request.get();
14028 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2914029 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5114030 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14031
danakj1fd259a02016-04-16 03:17:0914032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014034
[email protected]bd0b6772011-01-11 19:59:3014035 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114036 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014037 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114038 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014039
14040 // Complete the SSL handshake, which should abort due to requiring a
14041 // client certificate.
14042 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114043 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014044
14045 // Indicate that no certificate should be supplied. From the perspective
14046 // of SSLClientCertCache, NULL is just as meaningful as a real
14047 // certificate, so this is the same as supply a
14048 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614049 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114050 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014051
14052 // Ensure the certificate was added to the client auth cache before
14053 // allowing the connection to continue restarting.
14054 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414055 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114056 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414057 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214058 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014059
[email protected]bd0b6772011-01-11 19:59:3014060 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714061 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14062 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014063 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114064 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014065
14066 // Ensure that the client certificate is removed from the cache on a
14067 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114068 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414069 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014070}
14071
[email protected]8c405132011-01-11 22:03:1814072// Ensure that a client certificate is removed from the SSL client auth
14073// cache when:
14074// 1) An HTTPS proxy is involved.
14075// 3) The HTTPS proxy requests a client certificate.
14076// 4) The client supplies an invalid/unacceptable certificate for the
14077// proxy.
14078// The test is repeated twice, first for connecting to an HTTPS endpoint,
14079// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114080TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Lily Houghton8c2f97d2018-01-22 05:06:5914081 session_deps_.proxy_resolution_service =
14082 ProxyResolutionService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5114083 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714084 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814085
14086 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114087 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814088
14089 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14090 // [ssl_]data[1-3]. Rather than represending the endpoint
14091 // (www.example.com:443), they represent failures with the HTTPS proxy
14092 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914093 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814094 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714095 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2914096 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714097 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814098
ttuttle859dc7a2015-04-23 19:42:2914099 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814100 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914102 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714103 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814104
[email protected]80c75f682012-05-26 16:22:1714105 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14106#if 0
ttuttle859dc7a2015-04-23 19:42:2914107 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814108 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714109 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2914110 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0714111 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714112#endif
[email protected]8c405132011-01-11 22:03:1814113
ttuttle859dc7a2015-04-23 19:42:2914114 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814115 requests[0].url = GURL("https://www.example.com/");
14116 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914117 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814118
14119 requests[1].url = GURL("http://www.example.com/");
14120 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914121 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1814122
14123 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714124 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814127
14128 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114129 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014130 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114131 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814132
14133 // Complete the SSL handshake, which should abort due to requiring a
14134 // client certificate.
14135 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114136 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814137
14138 // Indicate that no certificate should be supplied. From the perspective
14139 // of SSLClientCertCache, NULL is just as meaningful as a real
14140 // certificate, so this is the same as supply a
14141 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614142 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114143 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814144
14145 // Ensure the certificate was added to the client auth cache before
14146 // allowing the connection to continue restarting.
14147 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414148 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114149 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414150 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214151 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814152 // Ensure the certificate was NOT cached for the endpoint. This only
14153 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114154 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414155 HostPortPair("www.example.com", 443), &client_cert,
14156 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814157
14158 // Restart the handshake. This will consume ssl_data2, which fails, and
14159 // then consume ssl_data3, which should also fail. The result code is
14160 // checked against what ssl_data3 should return.
14161 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114162 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814163
14164 // Now that the new handshake has failed, ensure that the client
14165 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114166 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414167 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114168 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414169 HostPortPair("www.example.com", 443), &client_cert,
14170 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814171 }
14172}
14173
bncd16676a2016-07-20 16:23:0114174TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614175 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914176 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914177 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614178
bnc032658ba2016-09-26 18:17:1514179 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614180
bncdf80d44fd2016-07-15 20:27:4114181 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914182 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814183 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114184 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714185 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614186 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114187 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614188 };
bnc42331402016-07-25 13:36:1514189 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114190 SpdySerializedFrame host1_resp_body(
14191 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514192 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114193 SpdySerializedFrame host2_resp_body(
14194 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614195 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114196 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14197 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314198 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614199 };
14200
eroman36d84e54432016-03-17 03:23:0214201 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214202 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314203 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14204 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714205 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614206
[email protected]aa22b242011-11-16 18:58:2914207 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614208 HttpRequestInfo request1;
14209 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314210 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614211 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014212 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614213
tfarina42834112016-09-22 13:38:2014214 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14216 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614217
14218 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214219 ASSERT_TRUE(response);
14220 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214221 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614222
14223 std::string response_data;
robpercival214763f2016-07-01 23:27:0114224 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614225 EXPECT_EQ("hello!", response_data);
14226
bnca4d611d2016-09-22 19:55:3714227 // Preload mail.example.com into HostCache.
14228 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014229 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614230 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014231 std::unique_ptr<HostResolver::Request> request;
14232 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14233 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014234 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714236 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114237 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614238
14239 HttpRequestInfo request2;
14240 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714241 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614242 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014243 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614244
tfarina42834112016-09-22 13:38:2014245 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14247 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614248
14249 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214250 ASSERT_TRUE(response);
14251 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214252 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614253 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214254 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114255 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614256 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614257}
14258
bncd16676a2016-07-20 16:23:0114259TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214260 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914261 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214263
bnc032658ba2016-09-26 18:17:1514264 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214265
bncdf80d44fd2016-07-15 20:27:4114266 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914267 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814268 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114269 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714270 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214271 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114272 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214273 };
bnc42331402016-07-25 13:36:1514274 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114275 SpdySerializedFrame host1_resp_body(
14276 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514277 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114278 SpdySerializedFrame host2_resp_body(
14279 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214280 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114281 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14282 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314283 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214284 };
14285
eroman36d84e54432016-03-17 03:23:0214286 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214287 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314288 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14289 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714290 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214291
14292 TestCompletionCallback callback;
14293 HttpRequestInfo request1;
14294 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314295 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214296 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014297 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214298
tfarina42834112016-09-22 13:38:2014299 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114300 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14301 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214302
14303 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214304 ASSERT_TRUE(response);
14305 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214306 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214307
14308 std::string response_data;
robpercival214763f2016-07-01 23:27:0114309 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214310 EXPECT_EQ("hello!", response_data);
14311
14312 HttpRequestInfo request2;
14313 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714314 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214315 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014316 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214317
tfarina42834112016-09-22 13:38:2014318 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14320 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214321
14322 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214323 ASSERT_TRUE(response);
14324 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214325 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214326 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214327 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114328 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214329 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214330}
14331
bnc8016c1f2017-03-31 02:11:2914332// Regression test for https://crbug.com/546991.
14333// The server might not be able to serve an IP pooled request, and might send a
14334// 421 Misdirected Request response status to indicate this.
14335// HttpNetworkTransaction should reset the request and retry without IP pooling.
14336TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14337 // Two hosts resolve to the same IP address.
14338 const std::string ip_addr = "1.2.3.4";
14339 IPAddress ip;
14340 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14341 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14342
Jeremy Roman0579ed62017-08-29 15:56:1914343 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914344 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14345 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14346
14347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14348
14349 // Two requests on the first connection.
14350 SpdySerializedFrame req1(
14351 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14352 spdy_util_.UpdateWithStreamDestruction(1);
14353 SpdySerializedFrame req2(
14354 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14355 SpdySerializedFrame rst(
14356 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14357 MockWrite writes1[] = {
14358 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14359 CreateMockWrite(rst, 6),
14360 };
14361
14362 // The first one succeeds, the second gets error 421 Misdirected Request.
14363 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14364 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14365 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714366 response_headers[kHttp2StatusHeader] = "421";
bnc8016c1f2017-03-31 02:11:2914367 SpdySerializedFrame resp2(
14368 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14369 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14370 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14371
14372 MockConnect connect1(ASYNC, OK, peer_addr);
14373 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14374 arraysize(writes1));
14375 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14376
14377 AddSSLSocketData();
14378
14379 // Retry the second request on a second connection.
14380 SpdyTestUtil spdy_util2;
14381 SpdySerializedFrame req3(
14382 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14383 MockWrite writes2[] = {
14384 CreateMockWrite(req3, 0),
14385 };
14386
14387 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14388 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14389 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14390 MockRead(ASYNC, 0, 3)};
14391
14392 MockConnect connect2(ASYNC, OK, peer_addr);
14393 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14394 arraysize(writes2));
14395 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14396
14397 AddSSLSocketData();
14398
14399 // Preload mail.example.org into HostCache.
14400 HostPortPair host_port("mail.example.org", 443);
14401 HostResolver::RequestInfo resolve_info(host_port);
14402 AddressList ignored;
14403 std::unique_ptr<HostResolver::Request> request;
14404 TestCompletionCallback callback;
14405 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14406 &ignored, callback.callback(),
14407 &request, NetLogWithSource());
14408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14409 rv = callback.WaitForResult();
14410 EXPECT_THAT(rv, IsOk());
14411
14412 HttpRequestInfo request1;
14413 request1.method = "GET";
14414 request1.url = GURL("https://www.example.org/");
14415 request1.load_flags = 0;
14416 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14417
14418 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14420 rv = callback.WaitForResult();
14421 EXPECT_THAT(rv, IsOk());
14422
14423 const HttpResponseInfo* response = trans1.GetResponseInfo();
14424 ASSERT_TRUE(response);
14425 ASSERT_TRUE(response->headers);
14426 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14427 EXPECT_TRUE(response->was_fetched_via_spdy);
14428 EXPECT_TRUE(response->was_alpn_negotiated);
14429 std::string response_data;
14430 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14431 EXPECT_EQ("hello!", response_data);
14432
14433 HttpRequestInfo request2;
14434 request2.method = "GET";
14435 request2.url = GURL("https://mail.example.org/");
14436 request2.load_flags = 0;
14437 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14438
14439 BoundTestNetLog log;
14440 rv = trans2.Start(&request2, callback.callback(), log.bound());
14441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14442 rv = callback.WaitForResult();
14443 EXPECT_THAT(rv, IsOk());
14444
14445 response = trans2.GetResponseInfo();
14446 ASSERT_TRUE(response);
14447 ASSERT_TRUE(response->headers);
14448 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14449 EXPECT_TRUE(response->was_fetched_via_spdy);
14450 EXPECT_TRUE(response->was_alpn_negotiated);
14451 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14452 EXPECT_EQ("hello!", response_data);
14453
14454 TestNetLogEntry::List entries;
14455 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914456 ExpectLogContainsSomewhere(
14457 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914458 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914459}
14460
14461// Test that HTTP 421 responses are properly returned to the caller if received
14462// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14463// portions of the response.
14464TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14465 // Two hosts resolve to the same IP address.
14466 const std::string ip_addr = "1.2.3.4";
14467 IPAddress ip;
14468 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14469 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14470
Jeremy Roman0579ed62017-08-29 15:56:1914471 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914472 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14473 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14474
14475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14476
14477 // Two requests on the first connection.
14478 SpdySerializedFrame req1(
14479 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14480 spdy_util_.UpdateWithStreamDestruction(1);
14481 SpdySerializedFrame req2(
14482 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14483 SpdySerializedFrame rst(
14484 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14485 MockWrite writes1[] = {
14486 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14487 CreateMockWrite(rst, 6),
14488 };
14489
14490 // The first one succeeds, the second gets error 421 Misdirected Request.
14491 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14492 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14493 SpdyHeaderBlock response_headers;
Bence Békybda82952017-10-02 17:35:2714494 response_headers[kHttp2StatusHeader] = "421";
davidbence688ae2017-05-04 15:12:5914495 SpdySerializedFrame resp2(
14496 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14497 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14498 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14499
14500 MockConnect connect1(ASYNC, OK, peer_addr);
14501 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14502 arraysize(writes1));
14503 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14504
14505 AddSSLSocketData();
14506
14507 // Retry the second request on a second connection. It returns 421 Misdirected
14508 // Retry again.
14509 SpdyTestUtil spdy_util2;
14510 SpdySerializedFrame req3(
14511 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14512 MockWrite writes2[] = {
14513 CreateMockWrite(req3, 0),
14514 };
14515
14516 SpdySerializedFrame resp3(
14517 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14518 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14519 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14520 MockRead(ASYNC, 0, 3)};
14521
14522 MockConnect connect2(ASYNC, OK, peer_addr);
14523 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14524 arraysize(writes2));
14525 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14526
14527 AddSSLSocketData();
14528
14529 // Preload mail.example.org into HostCache.
14530 HostPortPair host_port("mail.example.org", 443);
14531 HostResolver::RequestInfo resolve_info(host_port);
14532 AddressList ignored;
14533 std::unique_ptr<HostResolver::Request> request;
14534 TestCompletionCallback callback;
14535 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14536 &ignored, callback.callback(),
14537 &request, NetLogWithSource());
14538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14539 rv = callback.WaitForResult();
14540 EXPECT_THAT(rv, IsOk());
14541
14542 HttpRequestInfo request1;
14543 request1.method = "GET";
14544 request1.url = GURL("https://www.example.org/");
14545 request1.load_flags = 0;
14546 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14547
14548 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14549 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14550 rv = callback.WaitForResult();
14551 EXPECT_THAT(rv, IsOk());
14552
14553 const HttpResponseInfo* response = trans1.GetResponseInfo();
14554 ASSERT_TRUE(response);
14555 ASSERT_TRUE(response->headers);
14556 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14557 EXPECT_TRUE(response->was_fetched_via_spdy);
14558 EXPECT_TRUE(response->was_alpn_negotiated);
14559 std::string response_data;
14560 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14561 EXPECT_EQ("hello!", response_data);
14562
14563 HttpRequestInfo request2;
14564 request2.method = "GET";
14565 request2.url = GURL("https://mail.example.org/");
14566 request2.load_flags = 0;
14567 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14568
14569 BoundTestNetLog log;
14570 rv = trans2.Start(&request2, callback.callback(), log.bound());
14571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14572 rv = callback.WaitForResult();
14573 EXPECT_THAT(rv, IsOk());
14574
14575 // After a retry, the 421 Misdirected Request is reported back up to the
14576 // caller.
14577 response = trans2.GetResponseInfo();
14578 ASSERT_TRUE(response);
14579 ASSERT_TRUE(response->headers);
14580 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14581 EXPECT_TRUE(response->was_fetched_via_spdy);
14582 EXPECT_TRUE(response->was_alpn_negotiated);
14583 EXPECT_TRUE(response->ssl_info.cert);
14584 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14585 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914586}
14587
bnc6dcd8192017-05-25 20:11:5014588class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614589 public:
14590 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014591 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714592 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614593
dchengb03027d2014-10-21 12:00:2014594 int ResolveFromCache(const RequestInfo& info,
14595 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014596 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014597 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014598 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014599 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614600 return rv;
14601 }
14602
[email protected]e3ceb682011-06-28 23:55:4614603 private:
[email protected]e3ceb682011-06-28 23:55:4614604 const HostPortPair host_port_;
14605};
14606
bncd16676a2016-07-20 16:23:0114607TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314608 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614609 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914610 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714611 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614613
bnc032658ba2016-09-26 18:17:1514614 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614615
bncdf80d44fd2016-07-15 20:27:4114616 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914617 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814618 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114619 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714620 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614621 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114622 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614623 };
bnc42331402016-07-25 13:36:1514624 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114625 SpdySerializedFrame host1_resp_body(
14626 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514627 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114628 SpdySerializedFrame host2_resp_body(
14629 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614630 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114631 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14632 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314633 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614634 };
14635
eroman36d84e54432016-03-17 03:23:0214636 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214637 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314638 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14639 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714640 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614641
[email protected]aa22b242011-11-16 18:58:2914642 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614643 HttpRequestInfo request1;
14644 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314645 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614646 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014647 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614648
tfarina42834112016-09-22 13:38:2014649 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14651 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614652
14653 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214654 ASSERT_TRUE(response);
14655 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214656 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614657
14658 std::string response_data;
robpercival214763f2016-07-01 23:27:0114659 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614660 EXPECT_EQ("hello!", response_data);
14661
14662 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714663 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614664 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014665 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014666 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14667 &ignored, callback.callback(),
14668 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714670 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114671 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614672
14673 HttpRequestInfo request2;
14674 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714675 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614676 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014677 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614678
tfarina42834112016-09-22 13:38:2014679 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14681 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614682
14683 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214684 ASSERT_TRUE(response);
14685 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214686 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614687 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214688 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114689 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614690 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614691}
14692
bncd16676a2016-07-20 16:23:0114693TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314694 const std::string https_url = "https://www.example.org:8080/";
14695 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414696
14697 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114698 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914699 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414700
14701 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114702 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414703 };
14704
bnc42331402016-07-25 13:36:1514705 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114706 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14707 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914708 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414709
rch8e6c6c42015-05-01 14:05:1314710 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14711 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414712 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714713 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414714
14715 // HTTP GET for the HTTP URL
14716 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314717 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414718 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314719 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414720 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414721 };
14722
14723 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314724 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14725 MockRead(ASYNC, 2, "hello"),
14726 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414727 };
14728
rch8e6c6c42015-05-01 14:05:1314729 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14730 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414731
[email protected]8450d722012-07-02 19:14:0414732 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614733 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714734 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14735 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14736 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414737
danakj1fd259a02016-04-16 03:17:0914738 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414739
14740 // Start the first transaction to set up the SpdySession
14741 HttpRequestInfo request1;
14742 request1.method = "GET";
14743 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414744 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014745 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414746 TestCompletionCallback callback1;
14747 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014748 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514749 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414750
robpercival214763f2016-07-01 23:27:0114751 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414752 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14753
14754 // Now, start the HTTP request
14755 HttpRequestInfo request2;
14756 request2.method = "GET";
14757 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414758 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014759 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414760 TestCompletionCallback callback2;
14761 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014762 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514763 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414764
robpercival214763f2016-07-01 23:27:0114765 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414766 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14767}
14768
bnc5452e2a2015-05-08 16:27:4214769// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14770// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114771TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514772 url::SchemeHostPort server("https", "www.example.org", 443);
14773 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214774
bnc8bef8da22016-05-30 01:28:2514775 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214776 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614777 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14779
14780 // No data should be read from the alternative, because HTTP/1.1 is
14781 // negotiated.
14782 StaticSocketDataProvider data;
14783 session_deps_.socket_factory->AddSocketDataProvider(&data);
14784
14785 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614786 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214787 // mocked. This way the request relies on the alternate Job.
14788 StaticSocketDataProvider data_refused;
14789 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14790 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14791
zhongyi3d4a55e72016-04-22 20:36:4614792 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014794 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214795 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114796 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214797 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114798 http_server_properties->SetHttp2AlternativeService(
14799 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214800
bnc5452e2a2015-05-08 16:27:4214801 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214803 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514804 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214805 TestCompletionCallback callback;
14806
14807 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214808 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014809 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214810 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214811}
14812
bnc40448a532015-05-11 19:13:1414813// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614814// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414815// succeeds, the request should succeed, even if the latter fails because
14816// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114817TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514818 url::SchemeHostPort server("https", "www.example.org", 443);
14819 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414820
14821 // Negotiate HTTP/1.1 with alternative.
14822 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614823 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414824 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14825
14826 // No data should be read from the alternative, because HTTP/1.1 is
14827 // negotiated.
14828 StaticSocketDataProvider data;
14829 session_deps_.socket_factory->AddSocketDataProvider(&data);
14830
zhongyi3d4a55e72016-04-22 20:36:4614831 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414832 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614833 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414834 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14835
14836 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514837 MockWrite("GET / HTTP/1.1\r\n"
14838 "Host: www.example.org\r\n"
14839 "Connection: keep-alive\r\n\r\n"),
14840 MockWrite("GET /second HTTP/1.1\r\n"
14841 "Host: www.example.org\r\n"
14842 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414843 };
14844
14845 MockRead http_reads[] = {
14846 MockRead("HTTP/1.1 200 OK\r\n"),
14847 MockRead("Content-Type: text/html\r\n"),
14848 MockRead("Content-Length: 6\r\n\r\n"),
14849 MockRead("foobar"),
14850 MockRead("HTTP/1.1 200 OK\r\n"),
14851 MockRead("Content-Type: text/html\r\n"),
14852 MockRead("Content-Length: 7\r\n\r\n"),
14853 MockRead("another"),
14854 };
14855 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14856 http_writes, arraysize(http_writes));
14857 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14858
zhongyi3d4a55e72016-04-22 20:36:4614859 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014861 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414862 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114863 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214864 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114865 http_server_properties->SetHttp2AlternativeService(
14866 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414867
14868 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14869 HttpRequestInfo request1;
14870 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514871 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414872 request1.load_flags = 0;
14873 TestCompletionCallback callback1;
14874
tfarina42834112016-09-22 13:38:2014875 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414876 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114877 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414878
14879 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214880 ASSERT_TRUE(response1);
14881 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414882 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14883
14884 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114885 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414886 EXPECT_EQ("foobar", response_data1);
14887
14888 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14889 // for alternative service.
14890 EXPECT_TRUE(
14891 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14892
zhongyi3d4a55e72016-04-22 20:36:4614893 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414894 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614895 // to server.
bnc40448a532015-05-11 19:13:1414896 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14897 HttpRequestInfo request2;
14898 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514899 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414900 request2.load_flags = 0;
14901 TestCompletionCallback callback2;
14902
tfarina42834112016-09-22 13:38:2014903 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414904 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114905 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414906
14907 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214908 ASSERT_TRUE(response2);
14909 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414910 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14911
14912 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114913 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414914 EXPECT_EQ("another", response_data2);
14915}
14916
bnc5452e2a2015-05-08 16:27:4214917// Alternative service requires HTTP/2 (or SPDY), but there is already a
14918// HTTP/1.1 socket open to the alternative server. That socket should not be
14919// used.
bncd16676a2016-07-20 16:23:0114920TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614921 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214922 HostPortPair alternative("alternative.example.org", 443);
14923 std::string origin_url = "https://origin.example.org:443";
14924 std::string alternative_url = "https://alternative.example.org:443";
14925
14926 // Negotiate HTTP/1.1 with alternative.example.org.
14927 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614928 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214929 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14930
14931 // HTTP/1.1 data for |request1| and |request2|.
14932 MockWrite http_writes[] = {
14933 MockWrite(
14934 "GET / HTTP/1.1\r\n"
14935 "Host: alternative.example.org\r\n"
14936 "Connection: keep-alive\r\n\r\n"),
14937 MockWrite(
14938 "GET / HTTP/1.1\r\n"
14939 "Host: alternative.example.org\r\n"
14940 "Connection: keep-alive\r\n\r\n"),
14941 };
14942
14943 MockRead http_reads[] = {
14944 MockRead(
14945 "HTTP/1.1 200 OK\r\n"
14946 "Content-Type: text/html; charset=iso-8859-1\r\n"
14947 "Content-Length: 40\r\n\r\n"
14948 "first HTTP/1.1 response from alternative"),
14949 MockRead(
14950 "HTTP/1.1 200 OK\r\n"
14951 "Content-Type: text/html; charset=iso-8859-1\r\n"
14952 "Content-Length: 41\r\n\r\n"
14953 "second HTTP/1.1 response from alternative"),
14954 };
14955 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14956 http_writes, arraysize(http_writes));
14957 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14958
14959 // This test documents that an alternate Job should not pool to an already
14960 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614961 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214962 StaticSocketDataProvider data_refused;
14963 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14964 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14965
zhongyi3d4a55e72016-04-22 20:36:4614966 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914967 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014968 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214969 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114970 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214971 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114972 http_server_properties->SetHttp2AlternativeService(
14973 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214974
14975 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214976 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614977 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214978 request1.method = "GET";
14979 request1.url = GURL(alternative_url);
14980 request1.load_flags = 0;
14981 TestCompletionCallback callback1;
14982
tfarina42834112016-09-22 13:38:2014983 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114984 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614985 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214986 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214987 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214988 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214989 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214990 EXPECT_FALSE(response1->was_fetched_via_spdy);
14991 std::string response_data1;
bnc691fda62016-08-12 00:43:1614992 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214993 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14994
14995 // Request for origin.example.org, which has an alternative service. This
14996 // will start two Jobs: the alternative looks for connections to pool to,
14997 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614998 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214999 // this request fails.
bnc5452e2a2015-05-08 16:27:4215000 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615001 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215002 request2.method = "GET";
15003 request2.url = GURL(origin_url);
15004 request2.load_flags = 0;
15005 TestCompletionCallback callback2;
15006
tfarina42834112016-09-22 13:38:2015007 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115008 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215009
15010 // Another transaction to alternative. This is to test that the HTTP/1.1
15011 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215012 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615013 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215014 request3.method = "GET";
15015 request3.url = GURL(alternative_url);
15016 request3.load_flags = 0;
15017 TestCompletionCallback callback3;
15018
tfarina42834112016-09-22 13:38:2015019 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115020 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615021 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215022 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215023 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215024 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215025 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215026 EXPECT_FALSE(response3->was_fetched_via_spdy);
15027 std::string response_data3;
bnc691fda62016-08-12 00:43:1615028 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215029 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15030}
15031
bncd16676a2016-07-20 16:23:0115032TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315033 const std::string https_url = "https://www.example.org:8080/";
15034 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415035
rdsmithebb50aa2015-11-12 03:44:3815036 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115037 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815038
[email protected]8450d722012-07-02 19:14:0415039 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315040 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4115041 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415042 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4115043 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915044 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115045 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215046 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915047
15048 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2915049 SpdyHeaderBlock req2_block;
Bence Békybda82952017-10-02 17:35:2715050 req2_block[kHttp2MethodHeader] = "GET";
15051 req2_block[kHttp2AuthorityHeader] = "www.example.org:8080";
15052 req2_block[kHttp2SchemeHeader] = "http";
15053 req2_block[kHttp2PathHeader] = "/";
bncdf80d44fd2016-07-15 20:27:4115054 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515055 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415056
15057 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115058 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15059 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415060 };
15061
bncdf80d44fd2016-07-15 20:27:4115062 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515063 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115064 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515065 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115066 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15067 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815068 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4115069 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815070 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1515071 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4115072 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315073 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115074 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315075 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115076 CreateMockRead(wrapped_resp1, 4),
15077 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315078 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115079 CreateMockRead(resp2, 8),
15080 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315081 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15082 };
[email protected]8450d722012-07-02 19:14:0415083
mmenke666a6fea2015-12-19 04:16:3315084 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15085 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0415086 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715087 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415088
Lily Houghton8c2f97d2018-01-22 05:06:5915089 session_deps_.proxy_resolution_service =
15090 ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5115091 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715092 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415093 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615094 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315095 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415096 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615097 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15099 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415100
danakj1fd259a02016-04-16 03:17:0915101 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415102
15103 // Start the first transaction to set up the SpdySession
15104 HttpRequestInfo request1;
15105 request1.method = "GET";
15106 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415107 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015108 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415109 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015110 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415111
mmenke666a6fea2015-12-19 04:16:3315112 // This pause is a hack to avoid running into https://crbug.com/497228.
15113 data1.RunUntilPaused();
15114 base::RunLoop().RunUntilIdle();
15115 data1.Resume();
robpercival214763f2016-07-01 23:27:0115116 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415117 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15118
[email protected]f6c63db52013-02-02 00:35:2215119 LoadTimingInfo load_timing_info1;
15120 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15121 TestLoadTimingNotReusedWithPac(load_timing_info1,
15122 CONNECT_TIMING_HAS_SSL_TIMES);
15123
mmenke666a6fea2015-12-19 04:16:3315124 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415125 HttpRequestInfo request2;
15126 request2.method = "GET";
15127 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415128 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015129 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415130 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015131 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415132
mmenke666a6fea2015-12-19 04:16:3315133 // This pause is a hack to avoid running into https://crbug.com/497228.
15134 data1.RunUntilPaused();
15135 base::RunLoop().RunUntilIdle();
15136 data1.Resume();
robpercival214763f2016-07-01 23:27:0115137 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315138
[email protected]8450d722012-07-02 19:14:0415139 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215140
15141 LoadTimingInfo load_timing_info2;
15142 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15143 // The established SPDY sessions is considered reused by the HTTP request.
15144 TestLoadTimingReusedWithPac(load_timing_info2);
15145 // HTTP requests over a SPDY session should have a different connection
15146 // socket_log_id than requests over a tunnel.
15147 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415148}
15149
[email protected]2d88e7d2012-07-19 17:55:1715150// Test that in the case where we have a SPDY session to a SPDY proxy
15151// that we do not pool other origins that resolve to the same IP when
15152// the certificate does not match the new origin.
15153// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115154TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315155 const std::string url1 = "http://www.example.org/";
15156 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715157 const std::string ip_addr = "1.2.3.4";
15158
rdsmithebb50aa2015-11-12 03:44:3815159 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115160 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815161
[email protected]2d88e7d2012-07-19 17:55:1715162 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2615163 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315164 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4115165 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515166 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715167
15168 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115169 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715170 };
15171
bnc42331402016-07-25 13:36:1515172 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115173 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715174 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115175 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15176 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715177 };
15178
mmenke666a6fea2015-12-19 04:16:3315179 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
15180 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3215181 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915182 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715183 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15184 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315185 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715186
15187 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4115188 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915189 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715190
15191 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115192 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715193 };
15194
bnc42331402016-07-25 13:36:1515195 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115196 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
15197 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315198 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715199
mmenke666a6fea2015-12-19 04:16:3315200 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15201 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1715202 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315203 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715204
15205 // Set up a proxy config that sends HTTP requests to a proxy, and
15206 // all others direct.
15207 ProxyConfig proxy_config;
15208 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Lily Houghton8c2f97d2018-01-22 05:06:5915209 session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
Jeremy Roman0579ed62017-08-29 15:56:1915210 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5815211 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715212
bncce36dca22015-04-21 22:11:2315213 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615214 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715215 // Load a valid cert. Note, that this does not need to
15216 // be valid for proxy because the MockSSLClientSocket does
15217 // not actually verify it. But SpdySession will use this
15218 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915219 ssl1.ssl_info.cert =
15220 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15221 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315222 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15223 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715224
15225 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615226 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15228 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715229
Jeremy Roman0579ed62017-08-29 15:56:1915230 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315231 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715232 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715233
danakj1fd259a02016-04-16 03:17:0915234 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715235
15236 // Start the first transaction to set up the SpdySession
15237 HttpRequestInfo request1;
15238 request1.method = "GET";
15239 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715240 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015241 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715242 TestCompletionCallback callback1;
15243 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015244 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315245 // This pause is a hack to avoid running into https://crbug.com/497228.
15246 data1.RunUntilPaused();
15247 base::RunLoop().RunUntilIdle();
15248 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715249
robpercival214763f2016-07-01 23:27:0115250 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715251 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15252
15253 // Now, start the HTTP request
15254 HttpRequestInfo request2;
15255 request2.method = "GET";
15256 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715257 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015258 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715259 TestCompletionCallback callback2;
15260 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015261 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515262 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715263
15264 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115265 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715266 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15267}
15268
[email protected]85f97342013-04-17 06:12:2415269// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15270// error) in SPDY session, removes the socket from pool and closes the SPDY
15271// session. Verify that new url's from the same HttpNetworkSession (and a new
15272// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115273TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315274 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415275
15276 MockRead reads1[] = {
15277 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15278 };
15279
mmenke11eb5152015-06-09 14:50:5015280 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2415281
bncdf80d44fd2016-07-15 20:27:4115282 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915283 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415284 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115285 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415286 };
15287
bnc42331402016-07-25 13:36:1515288 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115289 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415290 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115291 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15292 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415293 };
15294
mmenke11eb5152015-06-09 14:50:5015295 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
15296 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2415297
[email protected]85f97342013-04-17 06:12:2415298 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615299 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015300 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15301 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415302
15303 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615304 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15306 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415307
danakj1fd259a02016-04-16 03:17:0915308 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015309 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415310
15311 // Start the first transaction to set up the SpdySession and verify that
15312 // connection was closed.
15313 HttpRequestInfo request1;
15314 request1.method = "GET";
15315 request1.url = GURL(https_url);
15316 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015317 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415318 TestCompletionCallback callback1;
15319 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015320 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115321 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415322
15323 // Now, start the second request and make sure it succeeds.
15324 HttpRequestInfo request2;
15325 request2.method = "GET";
15326 request2.url = GURL(https_url);
15327 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5015328 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415329 TestCompletionCallback callback2;
15330 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015331 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415332
robpercival214763f2016-07-01 23:27:0115333 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415334 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15335}
15336
bncd16676a2016-07-20 16:23:0115337TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315338 ClientSocketPoolManager::set_max_sockets_per_group(
15339 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15340 ClientSocketPoolManager::set_max_sockets_per_pool(
15341 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15342
15343 // Use two different hosts with different IPs so they don't get pooled.
15344 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15345 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915346 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315347
15348 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615349 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315350 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615351 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15354
bncdf80d44fd2016-07-15 20:27:4115355 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915356 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315357 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115358 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315359 };
bnc42331402016-07-25 13:36:1515360 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115361 SpdySerializedFrame host1_resp_body(
15362 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315363 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115364 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915365 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315366 };
15367
rdsmithebb50aa2015-11-12 03:44:3815368 // Use a separate test instance for the separate SpdySession that will be
15369 // created.
bncd16676a2016-07-20 16:23:0115370 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1915371 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815372 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
15373 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0315374 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
15375
bncdf80d44fd2016-07-15 20:27:4115376 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915377 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315378 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115379 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315380 };
bnc42331402016-07-25 13:36:1515381 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115382 SpdySerializedFrame host2_resp_body(
15383 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315384 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115385 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915386 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315387 };
15388
Jeremy Roman0579ed62017-08-29 15:56:1915389 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5815390 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
15391 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0315392 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
15393
15394 MockWrite http_write[] = {
15395 MockWrite("GET / HTTP/1.1\r\n"
15396 "Host: www.a.com\r\n"
15397 "Connection: keep-alive\r\n\r\n"),
15398 };
15399
15400 MockRead http_read[] = {
15401 MockRead("HTTP/1.1 200 OK\r\n"),
15402 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15403 MockRead("Content-Length: 6\r\n\r\n"),
15404 MockRead("hello!"),
15405 };
15406 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15407 http_write, arraysize(http_write));
15408 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15409
15410 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415411 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15412 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315413 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615414 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315415
15416 TestCompletionCallback callback;
15417 HttpRequestInfo request1;
15418 request1.method = "GET";
15419 request1.url = GURL("https://www.a.com/");
15420 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815421 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915422 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315423
tfarina42834112016-09-22 13:38:2015424 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15426 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315427
15428 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215429 ASSERT_TRUE(response);
15430 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215431 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315432 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215433 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315434
15435 std::string response_data;
robpercival214763f2016-07-01 23:27:0115436 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315437 EXPECT_EQ("hello!", response_data);
15438 trans.reset();
15439 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615440 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315441
15442 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415443 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15444 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315445 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615446 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315447 HttpRequestInfo request2;
15448 request2.method = "GET";
15449 request2.url = GURL("https://www.b.com/");
15450 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815451 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915452 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315453
tfarina42834112016-09-22 13:38:2015454 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15456 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315457
15458 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215459 ASSERT_TRUE(response);
15460 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215461 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315462 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215463 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115464 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315465 EXPECT_EQ("hello!", response_data);
15466 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615467 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315468 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615469 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315470
15471 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415472 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15473 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315474 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615475 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315476 HttpRequestInfo request3;
15477 request3.method = "GET";
15478 request3.url = GURL("http://www.a.com/");
15479 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815480 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915481 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315482
tfarina42834112016-09-22 13:38:2015483 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115484 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15485 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315486
15487 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215488 ASSERT_TRUE(response);
15489 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315490 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15491 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215492 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115493 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315494 EXPECT_EQ("hello!", response_data);
15495 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615496 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315497 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615498 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315499}
15500
bncd16676a2016-07-20 16:23:0115501TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415502 HttpRequestInfo request;
15503 request.method = "GET";
bncce36dca22015-04-21 22:11:2315504 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415505
danakj1fd259a02016-04-16 03:17:0915506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415508
ttuttled9dbc652015-09-29 20:00:5915509 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415510 StaticSocketDataProvider data;
15511 data.set_connect_data(mock_connect);
15512 session_deps_.socket_factory->AddSocketDataProvider(&data);
15513
15514 TestCompletionCallback callback;
15515
tfarina42834112016-09-22 13:38:2015516 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415518
15519 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115520 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415521
[email protected]79e1fd62013-06-20 06:50:0415522 // We don't care whether this succeeds or fails, but it shouldn't crash.
15523 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615524 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715525
15526 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615527 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715528 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115529 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915530
15531 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615532 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915533 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415534}
15535
bncd16676a2016-07-20 16:23:0115536TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415537 HttpRequestInfo request;
15538 request.method = "GET";
bncce36dca22015-04-21 22:11:2315539 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415540
danakj1fd259a02016-04-16 03:17:0915541 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615542 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415543
ttuttled9dbc652015-09-29 20:00:5915544 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415545 StaticSocketDataProvider data;
15546 data.set_connect_data(mock_connect);
15547 session_deps_.socket_factory->AddSocketDataProvider(&data);
15548
15549 TestCompletionCallback callback;
15550
tfarina42834112016-09-22 13:38:2015551 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415553
15554 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115555 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415556
[email protected]79e1fd62013-06-20 06:50:0415557 // We don't care whether this succeeds or fails, but it shouldn't crash.
15558 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615559 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715560
15561 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615562 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715563 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115564 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915565
15566 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615567 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915568 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415569}
15570
bncd16676a2016-07-20 16:23:0115571TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415572 HttpRequestInfo request;
15573 request.method = "GET";
bncce36dca22015-04-21 22:11:2315574 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415575
danakj1fd259a02016-04-16 03:17:0915576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615577 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415578
15579 MockWrite data_writes[] = {
15580 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15581 };
15582 MockRead data_reads[] = {
15583 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15584 };
15585
15586 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15587 data_writes, arraysize(data_writes));
15588 session_deps_.socket_factory->AddSocketDataProvider(&data);
15589
15590 TestCompletionCallback callback;
15591
tfarina42834112016-09-22 13:38:2015592 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115593 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415594
15595 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115596 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415597
[email protected]79e1fd62013-06-20 06:50:0415598 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615599 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415600 EXPECT_TRUE(request_headers.HasHeader("Host"));
15601}
15602
bncd16676a2016-07-20 16:23:0115603TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415604 HttpRequestInfo request;
15605 request.method = "GET";
bncce36dca22015-04-21 22:11:2315606 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415607
danakj1fd259a02016-04-16 03:17:0915608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615609 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415610
15611 MockWrite data_writes[] = {
15612 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15613 };
15614 MockRead data_reads[] = {
15615 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15616 };
15617
15618 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15619 data_writes, arraysize(data_writes));
15620 session_deps_.socket_factory->AddSocketDataProvider(&data);
15621
15622 TestCompletionCallback callback;
15623
tfarina42834112016-09-22 13:38:2015624 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415626
15627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115628 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415629
[email protected]79e1fd62013-06-20 06:50:0415630 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615631 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415632 EXPECT_TRUE(request_headers.HasHeader("Host"));
15633}
15634
bncd16676a2016-07-20 16:23:0115635TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415636 HttpRequestInfo request;
15637 request.method = "GET";
bncce36dca22015-04-21 22:11:2315638 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415639
danakj1fd259a02016-04-16 03:17:0915640 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615641 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415642
15643 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315644 MockWrite(
15645 "GET / HTTP/1.1\r\n"
15646 "Host: www.example.org\r\n"
15647 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415648 };
15649 MockRead data_reads[] = {
15650 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15651 };
15652
15653 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15654 data_writes, arraysize(data_writes));
15655 session_deps_.socket_factory->AddSocketDataProvider(&data);
15656
15657 TestCompletionCallback callback;
15658
tfarina42834112016-09-22 13:38:2015659 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415661
15662 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115663 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415664
[email protected]79e1fd62013-06-20 06:50:0415665 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615666 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415667 EXPECT_TRUE(request_headers.HasHeader("Host"));
15668}
15669
bncd16676a2016-07-20 16:23:0115670TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415671 HttpRequestInfo request;
15672 request.method = "GET";
bncce36dca22015-04-21 22:11:2315673 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415674
danakj1fd259a02016-04-16 03:17:0915675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415677
15678 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315679 MockWrite(
15680 "GET / HTTP/1.1\r\n"
15681 "Host: www.example.org\r\n"
15682 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415683 };
15684 MockRead data_reads[] = {
15685 MockRead(ASYNC, ERR_CONNECTION_RESET),
15686 };
15687
15688 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15689 data_writes, arraysize(data_writes));
15690 session_deps_.socket_factory->AddSocketDataProvider(&data);
15691
15692 TestCompletionCallback callback;
15693
tfarina42834112016-09-22 13:38:2015694 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415696
15697 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115698 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415699
[email protected]79e1fd62013-06-20 06:50:0415700 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615701 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415702 EXPECT_TRUE(request_headers.HasHeader("Host"));
15703}
15704
bncd16676a2016-07-20 16:23:0115705TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415706 HttpRequestInfo request;
15707 request.method = "GET";
bncce36dca22015-04-21 22:11:2315708 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415709 request.extra_headers.SetHeader("X-Foo", "bar");
15710
danakj1fd259a02016-04-16 03:17:0915711 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415713
15714 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315715 MockWrite(
15716 "GET / HTTP/1.1\r\n"
15717 "Host: www.example.org\r\n"
15718 "Connection: keep-alive\r\n"
15719 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415720 };
15721 MockRead data_reads[] = {
15722 MockRead("HTTP/1.1 200 OK\r\n"
15723 "Content-Length: 5\r\n\r\n"
15724 "hello"),
15725 MockRead(ASYNC, ERR_UNEXPECTED),
15726 };
15727
15728 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15729 data_writes, arraysize(data_writes));
15730 session_deps_.socket_factory->AddSocketDataProvider(&data);
15731
15732 TestCompletionCallback callback;
15733
tfarina42834112016-09-22 13:38:2015734 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415736
15737 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115738 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415739
15740 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615741 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415742 std::string foo;
15743 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15744 EXPECT_EQ("bar", foo);
15745}
15746
[email protected]bf828982013-08-14 18:01:4715747namespace {
15748
yhiranoa7e05bb2014-11-06 05:40:3915749// Fake HttpStream that simply records calls to SetPriority().
15750class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315751 public base::SupportsWeakPtr<FakeStream> {
15752 public:
15753 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
Chris Watkins7a41d3552017-12-01 02:13:2715754 ~FakeStream() override = default;
[email protected]e86839fd2013-08-14 18:29:0315755
15756 RequestPriority priority() const { return priority_; }
15757
dchengb03027d2014-10-21 12:00:2015758 int InitializeStream(const HttpRequestInfo* request_info,
Steven Valdezb4ff0412018-01-18 22:39:2715759 bool can_send_early,
dchengb03027d2014-10-21 12:00:2015760 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015761 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015762 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315763 return ERR_IO_PENDING;
15764 }
15765
dchengb03027d2014-10-21 12:00:2015766 int SendRequest(const HttpRequestHeaders& request_headers,
15767 HttpResponseInfo* response,
15768 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315769 ADD_FAILURE();
15770 return ERR_UNEXPECTED;
15771 }
15772
dchengb03027d2014-10-21 12:00:2015773 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315774 ADD_FAILURE();
15775 return ERR_UNEXPECTED;
15776 }
15777
dchengb03027d2014-10-21 12:00:2015778 int ReadResponseBody(IOBuffer* buf,
15779 int buf_len,
15780 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315781 ADD_FAILURE();
15782 return ERR_UNEXPECTED;
15783 }
15784
dchengb03027d2014-10-21 12:00:2015785 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315786
dchengb03027d2014-10-21 12:00:2015787 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315788 ADD_FAILURE();
15789 return false;
15790 }
15791
dchengb03027d2014-10-21 12:00:2015792 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315793 ADD_FAILURE();
15794 return false;
15795 }
15796
dchengb03027d2014-10-21 12:00:2015797 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315798
mmenkebd84c392015-09-02 14:12:3415799 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315800
sclittle4de1bab92015-09-22 21:28:2415801 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915802 ADD_FAILURE();
15803 return 0;
15804 }
15805
sclittlebe1ccf62015-09-02 19:40:3615806 int64_t GetTotalSentBytes() const override {
15807 ADD_FAILURE();
15808 return 0;
15809 }
15810
dchengb03027d2014-10-21 12:00:2015811 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315812 ADD_FAILURE();
15813 return false;
15814 }
15815
rchcd379012017-04-12 21:53:3215816 bool GetAlternativeService(
15817 AlternativeService* alternative_service) const override {
15818 ADD_FAILURE();
15819 return false;
15820 }
15821
dchengb03027d2014-10-21 12:00:2015822 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15823
15824 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315825 ADD_FAILURE();
15826 }
15827
ttuttled9dbc652015-09-29 20:00:5915828 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15829
nharper78e6d2b2016-09-21 05:42:3515830 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15831 TokenBindingType tb_type,
15832 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415833 ADD_FAILURE();
15834 return ERR_NOT_IMPLEMENTED;
15835 }
15836
dchengb03027d2014-10-21 12:00:2015837 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315838
zhongyica364fbb2015-12-12 03:39:1215839 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15840
dchengb03027d2014-10-21 12:00:2015841 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315842
yhiranoa7e05bb2014-11-06 05:40:3915843 HttpStream* RenewStreamForAuth() override { return NULL; }
15844
Andrey Kosyakov83a6eee2017-08-14 19:20:0415845 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15846
[email protected]e86839fd2013-08-14 18:29:0315847 private:
15848 RequestPriority priority_;
15849
15850 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15851};
15852
15853// Fake HttpStreamRequest that simply records calls to SetPriority()
15854// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715855class FakeStreamRequest : public HttpStreamRequest,
15856 public base::SupportsWeakPtr<FakeStreamRequest> {
15857 public:
[email protected]e86839fd2013-08-14 18:29:0315858 FakeStreamRequest(RequestPriority priority,
15859 HttpStreamRequest::Delegate* delegate)
15860 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415861 delegate_(delegate),
15862 websocket_stream_create_helper_(NULL) {}
15863
15864 FakeStreamRequest(RequestPriority priority,
15865 HttpStreamRequest::Delegate* delegate,
15866 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15867 : priority_(priority),
15868 delegate_(delegate),
15869 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315870
Chris Watkins7a41d3552017-12-01 02:13:2715871 ~FakeStreamRequest() override = default;
[email protected]bf828982013-08-14 18:01:4715872
15873 RequestPriority priority() const { return priority_; }
15874
[email protected]831e4a32013-11-14 02:14:4415875 const WebSocketHandshakeStreamBase::CreateHelper*
15876 websocket_stream_create_helper() const {
15877 return websocket_stream_create_helper_;
15878 }
15879
[email protected]e86839fd2013-08-14 18:29:0315880 // Create a new FakeStream and pass it to the request's
15881 // delegate. Returns a weak pointer to the FakeStream.
15882 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915883 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315884 // Do this before calling OnStreamReady() as OnStreamReady() may
15885 // immediately delete |fake_stream|.
15886 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015887 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315888 return weak_stream;
15889 }
15890
asanka681f02d2017-02-22 17:06:3915891 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715892 ADD_FAILURE();
15893 return ERR_UNEXPECTED;
15894 }
15895
dchengb03027d2014-10-21 12:00:2015896 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715897 ADD_FAILURE();
15898 return LoadState();
15899 }
15900
dchengb03027d2014-10-21 12:00:2015901 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715902
bnc94c92842016-09-21 15:22:5215903 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715904
bnc6227b26e2016-08-12 02:00:4315905 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715906
dchengb03027d2014-10-21 12:00:2015907 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715908
ttuttle1f2d7e92015-04-28 16:17:4715909 const ConnectionAttempts& connection_attempts() const override {
15910 static ConnectionAttempts no_attempts;
15911 return no_attempts;
15912 }
15913
[email protected]bf828982013-08-14 18:01:4715914 private:
15915 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315916 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415917 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715918
15919 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15920};
15921
15922// Fake HttpStreamFactory that vends FakeStreamRequests.
15923class FakeStreamFactory : public HttpStreamFactory {
15924 public:
Chris Watkins7a41d3552017-12-01 02:13:2715925 FakeStreamFactory() = default;
15926 ~FakeStreamFactory() override = default;
[email protected]bf828982013-08-14 18:01:4715927
15928 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15929 // RequestStream() (which may be NULL if it was destroyed already).
15930 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15931 return last_stream_request_;
15932 }
15933
xunjieli96f2a402017-06-05 17:24:2715934 std::unique_ptr<HttpStreamRequest> RequestStream(
15935 const HttpRequestInfo& info,
15936 RequestPriority priority,
15937 const SSLConfig& server_ssl_config,
15938 const SSLConfig& proxy_ssl_config,
15939 HttpStreamRequest::Delegate* delegate,
15940 bool enable_ip_based_pooling,
15941 bool enable_alternative_services,
15942 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915943 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715944 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715945 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715946 }
15947
xunjieli96f2a402017-06-05 17:24:2715948 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815949 const HttpRequestInfo& info,
15950 RequestPriority priority,
15951 const SSLConfig& server_ssl_config,
15952 const SSLConfig& proxy_ssl_config,
15953 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915954 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615955 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015956 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815957 NOTREACHED();
15958 return nullptr;
15959 }
15960
xunjieli96f2a402017-06-05 17:24:2715961 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715962 const HttpRequestInfo& info,
15963 RequestPriority priority,
15964 const SSLConfig& server_ssl_config,
15965 const SSLConfig& proxy_ssl_config,
15966 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615967 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915968 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615969 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015970 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715971 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915972 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415973 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715974 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715975 }
15976
dchengb03027d2014-10-21 12:00:2015977 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915978 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715979 ADD_FAILURE();
15980 }
15981
dchengb03027d2014-10-21 12:00:2015982 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715983 ADD_FAILURE();
15984 return NULL;
15985 }
15986
xunjielif5267de2017-01-20 21:18:5715987 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15988 const std::string& parent_absolute_name) const override {
15989 ADD_FAILURE();
15990 }
15991
[email protected]bf828982013-08-14 18:01:4715992 private:
15993 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15994
15995 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15996};
15997
[email protected]bf828982013-08-14 18:01:4715998} // namespace
15999
16000// Make sure that HttpNetworkTransaction passes on its priority to its
16001// stream request on start.
bncd16676a2016-07-20 16:23:0116002TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0916003 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216004 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716005 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916006 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716007
krasinc06a72a2016-12-21 03:42:4616008 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116009 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716010
wezca1070932016-05-26 20:30:5216011 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4716012
[email protected]bf828982013-08-14 18:01:4716013 TestCompletionCallback callback;
16014 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016015 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716016
16017 base::WeakPtr<FakeStreamRequest> fake_request =
16018 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216019 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716020 EXPECT_EQ(LOW, fake_request->priority());
16021}
16022
16023// Make sure that HttpNetworkTransaction passes on its priority
16024// updates to its stream request.
bncd16676a2016-07-20 16:23:0116025TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0916026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216027 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4716028 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916029 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4716030
krasinc06a72a2016-12-21 03:42:4616031 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116032 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4716033
[email protected]bf828982013-08-14 18:01:4716034 TestCompletionCallback callback;
16035 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016036 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4716037
16038 base::WeakPtr<FakeStreamRequest> fake_request =
16039 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216040 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716041 EXPECT_EQ(LOW, fake_request->priority());
16042
16043 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5216044 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4716045 EXPECT_EQ(LOWEST, fake_request->priority());
16046}
16047
[email protected]e86839fd2013-08-14 18:29:0316048// Make sure that HttpNetworkTransaction passes on its priority
16049// updates to its stream.
bncd16676a2016-07-20 16:23:0116050TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0916051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4216052 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0316053 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0916054 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0316055
krasinc06a72a2016-12-21 03:42:4616056 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4116057 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0316058
[email protected]e86839fd2013-08-14 18:29:0316059 TestCompletionCallback callback;
16060 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016061 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0316062
16063 base::WeakPtr<FakeStreamRequest> fake_request =
16064 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5216065 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0316066 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5216067 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0316068 EXPECT_EQ(LOW, fake_stream->priority());
16069
16070 trans.SetPriority(LOWEST);
16071 EXPECT_EQ(LOWEST, fake_stream->priority());
16072}
16073
[email protected]043b68c82013-08-22 23:41:5216074// Tests that when a used socket is returned to the SSL socket pool, it's closed
16075// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116076TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216077 ClientSocketPoolManager::set_max_sockets_per_group(
16078 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16079 ClientSocketPoolManager::set_max_sockets_per_pool(
16080 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16081
16082 // Set up SSL request.
16083
16084 HttpRequestInfo ssl_request;
16085 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316086 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216087
16088 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316089 MockWrite(
16090 "GET / HTTP/1.1\r\n"
16091 "Host: www.example.org\r\n"
16092 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216093 };
16094 MockRead ssl_reads[] = {
16095 MockRead("HTTP/1.1 200 OK\r\n"),
16096 MockRead("Content-Length: 11\r\n\r\n"),
16097 MockRead("hello world"),
16098 MockRead(SYNCHRONOUS, OK),
16099 };
16100 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
16101 ssl_writes, arraysize(ssl_writes));
16102 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16103
16104 SSLSocketDataProvider ssl(ASYNC, OK);
16105 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16106
16107 // Set up HTTP request.
16108
16109 HttpRequestInfo http_request;
16110 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316111 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216112
16113 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316114 MockWrite(
16115 "GET / HTTP/1.1\r\n"
16116 "Host: www.example.org\r\n"
16117 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216118 };
16119 MockRead http_reads[] = {
16120 MockRead("HTTP/1.1 200 OK\r\n"),
16121 MockRead("Content-Length: 7\r\n\r\n"),
16122 MockRead("falafel"),
16123 MockRead(SYNCHRONOUS, OK),
16124 };
16125 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16126 http_writes, arraysize(http_writes));
16127 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16128
danakj1fd259a02016-04-16 03:17:0916129 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216130
16131 // Start the SSL request.
16132 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616133 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016134 ASSERT_EQ(ERR_IO_PENDING,
16135 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16136 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216137
16138 // Start the HTTP request. Pool should stall.
16139 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616140 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016141 ASSERT_EQ(ERR_IO_PENDING,
16142 http_trans.Start(&http_request, http_callback.callback(),
16143 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116144 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216145
16146 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116147 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216148 std::string response_data;
bnc691fda62016-08-12 00:43:1616149 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216150 EXPECT_EQ("hello world", response_data);
16151
16152 // The SSL socket should automatically be closed, so the HTTP request can
16153 // start.
dcheng48459ac22014-08-26 00:46:4116154 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16155 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216156
16157 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116158 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616159 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216160 EXPECT_EQ("falafel", response_data);
16161
dcheng48459ac22014-08-26 00:46:4116162 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216163}
16164
16165// Tests that when a SSL connection is established but there's no corresponding
16166// request that needs it, the new socket is closed if the transport socket pool
16167// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116168TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216169 ClientSocketPoolManager::set_max_sockets_per_group(
16170 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16171 ClientSocketPoolManager::set_max_sockets_per_pool(
16172 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16173
16174 // Set up an ssl request.
16175
16176 HttpRequestInfo ssl_request;
16177 ssl_request.method = "GET";
16178 ssl_request.url = GURL("https://www.foopy.com/");
16179
16180 // No data will be sent on the SSL socket.
16181 StaticSocketDataProvider ssl_data;
16182 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16183
16184 SSLSocketDataProvider ssl(ASYNC, OK);
16185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16186
16187 // Set up HTTP request.
16188
16189 HttpRequestInfo http_request;
16190 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316191 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5216192
16193 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316194 MockWrite(
16195 "GET / HTTP/1.1\r\n"
16196 "Host: www.example.org\r\n"
16197 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216198 };
16199 MockRead http_reads[] = {
16200 MockRead("HTTP/1.1 200 OK\r\n"),
16201 MockRead("Content-Length: 7\r\n\r\n"),
16202 MockRead("falafel"),
16203 MockRead(SYNCHRONOUS, OK),
16204 };
16205 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
16206 http_writes, arraysize(http_writes));
16207 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16208
danakj1fd259a02016-04-16 03:17:0916209 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216210
16211 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16212 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916213 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916214 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116215 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216216
16217 // Start the HTTP request. Pool should stall.
16218 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616219 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016220 ASSERT_EQ(ERR_IO_PENDING,
16221 http_trans.Start(&http_request, http_callback.callback(),
16222 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116223 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216224
16225 // The SSL connection will automatically be closed once the connection is
16226 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116227 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216228 std::string response_data;
bnc691fda62016-08-12 00:43:1616229 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216230 EXPECT_EQ("falafel", response_data);
16231
dcheng48459ac22014-08-26 00:46:4116232 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216233}
16234
bncd16676a2016-07-20 16:23:0116235TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916236 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216237 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916238 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216239 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416240
16241 HttpRequestInfo request;
16242 request.method = "POST";
16243 request.url = GURL("http://www.foo.com/");
16244 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416245
danakj1fd259a02016-04-16 03:17:0916246 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616247 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416248 // Send headers successfully, but get an error while sending the body.
16249 MockWrite data_writes[] = {
16250 MockWrite("POST / HTTP/1.1\r\n"
16251 "Host: www.foo.com\r\n"
16252 "Connection: keep-alive\r\n"
16253 "Content-Length: 3\r\n\r\n"),
16254 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16255 };
16256
16257 MockRead data_reads[] = {
16258 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16259 MockRead("hello world"),
16260 MockRead(SYNCHRONOUS, OK),
16261 };
16262 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16263 arraysize(data_writes));
16264 session_deps_.socket_factory->AddSocketDataProvider(&data);
16265
16266 TestCompletionCallback callback;
16267
tfarina42834112016-09-22 13:38:2016268 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116269 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416270
16271 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116272 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416273
bnc691fda62016-08-12 00:43:1616274 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216275 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416276
wezca1070932016-05-26 20:30:5216277 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416278 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16279
16280 std::string response_data;
bnc691fda62016-08-12 00:43:1616281 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116282 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416283 EXPECT_EQ("hello world", response_data);
16284}
16285
16286// This test makes sure the retry logic doesn't trigger when reading an error
16287// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116288TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416289 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416291 MockWrite data_writes[] = {
16292 MockWrite("GET / HTTP/1.1\r\n"
16293 "Host: www.foo.com\r\n"
16294 "Connection: keep-alive\r\n\r\n"),
16295 MockWrite("POST / HTTP/1.1\r\n"
16296 "Host: www.foo.com\r\n"
16297 "Connection: keep-alive\r\n"
16298 "Content-Length: 3\r\n\r\n"),
16299 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16300 };
16301
16302 MockRead data_reads[] = {
16303 MockRead("HTTP/1.1 200 Peachy\r\n"
16304 "Content-Length: 14\r\n\r\n"),
16305 MockRead("first response"),
16306 MockRead("HTTP/1.1 400 Not OK\r\n"
16307 "Content-Length: 15\r\n\r\n"),
16308 MockRead("second response"),
16309 MockRead(SYNCHRONOUS, OK),
16310 };
16311 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16312 arraysize(data_writes));
16313 session_deps_.socket_factory->AddSocketDataProvider(&data);
16314
16315 TestCompletionCallback callback;
16316 HttpRequestInfo request1;
16317 request1.method = "GET";
16318 request1.url = GURL("http://www.foo.com/");
16319 request1.load_flags = 0;
16320
bnc87dcefc2017-05-25 12:47:5816321 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916322 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016323 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416325
16326 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116327 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416328
16329 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216330 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416331
wezca1070932016-05-26 20:30:5216332 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416333 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16334
16335 std::string response_data1;
16336 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116337 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416338 EXPECT_EQ("first response", response_data1);
16339 // Delete the transaction to release the socket back into the socket pool.
16340 trans1.reset();
16341
danakj1fd259a02016-04-16 03:17:0916342 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216343 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916344 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216345 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416346
16347 HttpRequestInfo request2;
16348 request2.method = "POST";
16349 request2.url = GURL("http://www.foo.com/");
16350 request2.upload_data_stream = &upload_data_stream;
16351 request2.load_flags = 0;
16352
bnc691fda62016-08-12 00:43:1616353 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016354 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416356
16357 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116358 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416359
bnc691fda62016-08-12 00:43:1616360 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216361 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416362
wezca1070932016-05-26 20:30:5216363 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416364 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16365
16366 std::string response_data2;
bnc691fda62016-08-12 00:43:1616367 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116368 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416369 EXPECT_EQ("second response", response_data2);
16370}
16371
bncd16676a2016-07-20 16:23:0116372TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416373 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916374 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216375 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916376 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216377 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416378
16379 HttpRequestInfo request;
16380 request.method = "POST";
16381 request.url = GURL("http://www.foo.com/");
16382 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416383
danakj1fd259a02016-04-16 03:17:0916384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616385 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416386 // Send headers successfully, but get an error while sending the body.
16387 MockWrite data_writes[] = {
16388 MockWrite("POST / HTTP/1.1\r\n"
16389 "Host: www.foo.com\r\n"
16390 "Connection: keep-alive\r\n"
16391 "Content-Length: 3\r\n\r\n"
16392 "fo"),
16393 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16394 };
16395
16396 MockRead data_reads[] = {
16397 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16398 MockRead("hello world"),
16399 MockRead(SYNCHRONOUS, OK),
16400 };
16401 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16402 arraysize(data_writes));
16403 session_deps_.socket_factory->AddSocketDataProvider(&data);
16404
16405 TestCompletionCallback callback;
16406
tfarina42834112016-09-22 13:38:2016407 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416409
16410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116411 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416412
bnc691fda62016-08-12 00:43:1616413 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216414 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416415
wezca1070932016-05-26 20:30:5216416 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416417 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16418
16419 std::string response_data;
bnc691fda62016-08-12 00:43:1616420 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116421 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416422 EXPECT_EQ("hello world", response_data);
16423}
16424
16425// This tests the more common case than the previous test, where headers and
16426// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116427TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716428 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416429
16430 HttpRequestInfo request;
16431 request.method = "POST";
16432 request.url = GURL("http://www.foo.com/");
16433 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416434
danakj1fd259a02016-04-16 03:17:0916435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416437 // Send headers successfully, but get an error while sending the body.
16438 MockWrite data_writes[] = {
16439 MockWrite("POST / HTTP/1.1\r\n"
16440 "Host: www.foo.com\r\n"
16441 "Connection: keep-alive\r\n"
16442 "Transfer-Encoding: chunked\r\n\r\n"),
16443 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16444 };
16445
16446 MockRead data_reads[] = {
16447 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16448 MockRead("hello world"),
16449 MockRead(SYNCHRONOUS, OK),
16450 };
16451 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16452 arraysize(data_writes));
16453 session_deps_.socket_factory->AddSocketDataProvider(&data);
16454
16455 TestCompletionCallback callback;
16456
tfarina42834112016-09-22 13:38:2016457 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416459 // Make sure the headers are sent before adding a chunk. This ensures that
16460 // they can't be merged with the body in a single send. Not currently
16461 // necessary since a chunked body is never merged with headers, but this makes
16462 // the test more future proof.
16463 base::RunLoop().RunUntilIdle();
16464
mmenkecbc2b712014-10-09 20:29:0716465 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416466
16467 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116468 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416469
bnc691fda62016-08-12 00:43:1616470 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216471 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416472
wezca1070932016-05-26 20:30:5216473 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416474 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16475
16476 std::string response_data;
bnc691fda62016-08-12 00:43:1616477 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116478 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416479 EXPECT_EQ("hello world", response_data);
16480}
16481
bncd16676a2016-07-20 16:23:0116482TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916483 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216484 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916485 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216486 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416487
16488 HttpRequestInfo request;
16489 request.method = "POST";
16490 request.url = GURL("http://www.foo.com/");
16491 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416492
danakj1fd259a02016-04-16 03:17:0916493 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416495
16496 MockWrite data_writes[] = {
16497 MockWrite("POST / HTTP/1.1\r\n"
16498 "Host: www.foo.com\r\n"
16499 "Connection: keep-alive\r\n"
16500 "Content-Length: 3\r\n\r\n"),
16501 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16502 };
16503
16504 MockRead data_reads[] = {
16505 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16506 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16507 MockRead("hello world"),
16508 MockRead(SYNCHRONOUS, OK),
16509 };
16510 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16511 arraysize(data_writes));
16512 session_deps_.socket_factory->AddSocketDataProvider(&data);
16513
16514 TestCompletionCallback callback;
16515
tfarina42834112016-09-22 13:38:2016516 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416518
16519 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116520 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416521
bnc691fda62016-08-12 00:43:1616522 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216523 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416524
wezca1070932016-05-26 20:30:5216525 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416526 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16527
16528 std::string response_data;
bnc691fda62016-08-12 00:43:1616529 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116530 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416531 EXPECT_EQ("hello world", response_data);
16532}
16533
bncd16676a2016-07-20 16:23:0116534TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916535 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216536 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916537 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216538 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416539
16540 HttpRequestInfo request;
16541 request.method = "POST";
16542 request.url = GURL("http://www.foo.com/");
16543 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416544
danakj1fd259a02016-04-16 03:17:0916545 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416547 // Send headers successfully, but get an error while sending the body.
16548 MockWrite data_writes[] = {
16549 MockWrite("POST / HTTP/1.1\r\n"
16550 "Host: www.foo.com\r\n"
16551 "Connection: keep-alive\r\n"
16552 "Content-Length: 3\r\n\r\n"),
16553 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16554 };
16555
16556 MockRead data_reads[] = {
16557 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16558 MockRead("hello world"),
16559 MockRead(SYNCHRONOUS, OK),
16560 };
16561 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16562 arraysize(data_writes));
16563 session_deps_.socket_factory->AddSocketDataProvider(&data);
16564
16565 TestCompletionCallback callback;
16566
tfarina42834112016-09-22 13:38:2016567 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416569
16570 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116571 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416572}
16573
bncd16676a2016-07-20 16:23:0116574TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416575 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916576 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216577 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916578 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216579 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416580
16581 HttpRequestInfo request;
16582 request.method = "POST";
16583 request.url = GURL("http://www.foo.com/");
16584 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416585
danakj1fd259a02016-04-16 03:17:0916586 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416588 // Send headers successfully, but get an error while sending the body.
16589 MockWrite data_writes[] = {
16590 MockWrite("POST / HTTP/1.1\r\n"
16591 "Host: www.foo.com\r\n"
16592 "Connection: keep-alive\r\n"
16593 "Content-Length: 3\r\n\r\n"),
16594 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16595 };
16596
16597 MockRead data_reads[] = {
16598 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16599 MockRead("HTTP/1.0 302 Redirect\r\n"),
16600 MockRead("Location: http://somewhere-else.com/\r\n"),
16601 MockRead("Content-Length: 0\r\n\r\n"),
16602 MockRead(SYNCHRONOUS, OK),
16603 };
16604 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16605 arraysize(data_writes));
16606 session_deps_.socket_factory->AddSocketDataProvider(&data);
16607
16608 TestCompletionCallback callback;
16609
tfarina42834112016-09-22 13:38:2016610 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416612
16613 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116614 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416615}
16616
bncd16676a2016-07-20 16:23:0116617TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916618 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216619 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916620 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216621 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416622
16623 HttpRequestInfo request;
16624 request.method = "POST";
16625 request.url = GURL("http://www.foo.com/");
16626 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416627
danakj1fd259a02016-04-16 03:17:0916628 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616629 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416630 // Send headers successfully, but get an error while sending the body.
16631 MockWrite data_writes[] = {
16632 MockWrite("POST / HTTP/1.1\r\n"
16633 "Host: www.foo.com\r\n"
16634 "Connection: keep-alive\r\n"
16635 "Content-Length: 3\r\n\r\n"),
16636 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16637 };
16638
16639 MockRead data_reads[] = {
16640 MockRead("HTTP 0.9 rocks!"),
16641 MockRead(SYNCHRONOUS, OK),
16642 };
16643 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16644 arraysize(data_writes));
16645 session_deps_.socket_factory->AddSocketDataProvider(&data);
16646
16647 TestCompletionCallback callback;
16648
tfarina42834112016-09-22 13:38:2016649 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416651
16652 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116653 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416654}
16655
bncd16676a2016-07-20 16:23:0116656TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916657 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216658 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916659 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216660 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416661
16662 HttpRequestInfo request;
16663 request.method = "POST";
16664 request.url = GURL("http://www.foo.com/");
16665 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416666
danakj1fd259a02016-04-16 03:17:0916667 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616668 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416669 // Send headers successfully, but get an error while sending the body.
16670 MockWrite data_writes[] = {
16671 MockWrite("POST / HTTP/1.1\r\n"
16672 "Host: www.foo.com\r\n"
16673 "Connection: keep-alive\r\n"
16674 "Content-Length: 3\r\n\r\n"),
16675 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16676 };
16677
16678 MockRead data_reads[] = {
16679 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16680 MockRead(SYNCHRONOUS, OK),
16681 };
16682 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16683 arraysize(data_writes));
16684 session_deps_.socket_factory->AddSocketDataProvider(&data);
16685
16686 TestCompletionCallback callback;
16687
tfarina42834112016-09-22 13:38:2016688 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416690
16691 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116692 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416693}
16694
Bence Békydca6bd92018-01-30 13:43:0616695#if BUILDFLAG(ENABLE_WEBSOCKETS)
16696
16697namespace {
16698
16699void AddWebSocketHeaders(HttpRequestHeaders* headers) {
16700 headers->SetHeader("Connection", "Upgrade");
16701 headers->SetHeader("Upgrade", "websocket");
16702 headers->SetHeader("Origin", "http://www.example.org");
16703 headers->SetHeader("Sec-WebSocket-Version", "13");
16704 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
16705}
16706
16707} // namespace
16708
16709TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
16710 // The same logic needs to be tested for both ws: and wss: schemes, but this
16711 // test is already parameterised on NextProto, so it uses a loop to verify
16712 // that the different schemes work.
16713 std::string test_cases[] = {"ws://www.example.org/",
16714 "wss://www.example.org/"};
16715 for (size_t i = 0; i < arraysize(test_cases); ++i) {
16716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16717 HttpNetworkSessionPeer peer(session.get());
16718 FakeStreamFactory* fake_factory = new FakeStreamFactory();
16719 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
16720
16721 HttpRequestInfo request;
16722 request.method = "GET";
16723 request.url = GURL(test_cases[i]);
16724
16725 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16726 HttpNetworkTransaction trans(LOW, session.get());
16727 trans.SetWebSocketHandshakeStreamCreateHelper(
16728 &websocket_stream_create_helper);
16729
16730 TestCompletionCallback callback;
16731 EXPECT_EQ(ERR_IO_PENDING,
16732 trans.Start(&request, callback.callback(), NetLogWithSource()));
16733
16734 base::WeakPtr<FakeStreamRequest> fake_request =
16735 fake_factory->last_stream_request();
16736 ASSERT_TRUE(fake_request);
16737 EXPECT_EQ(&websocket_stream_create_helper,
16738 fake_request->websocket_stream_create_helper());
16739 }
16740}
16741
Adam Rice425cf122015-01-19 06:18:2416742// Verify that proxy headers are not sent to the destination server when
16743// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116744TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416745 HttpRequestInfo request;
16746 request.method = "GET";
bncce36dca22015-04-21 22:11:2316747 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416748 AddWebSocketHeaders(&request.extra_headers);
16749
16750 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916751 session_deps_.proxy_resolution_service =
16752 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416753
danakj1fd259a02016-04-16 03:17:0916754 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416755
16756 // Since a proxy is configured, try to establish a tunnel.
16757 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716758 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16759 "Host: www.example.org:443\r\n"
16760 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416761
16762 // After calling trans->RestartWithAuth(), this is the request we should
16763 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716764 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16765 "Host: www.example.org:443\r\n"
16766 "Proxy-Connection: keep-alive\r\n"
16767 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416768
rsleevidb16bb02015-11-12 23:47:1716769 MockWrite("GET / HTTP/1.1\r\n"
16770 "Host: www.example.org\r\n"
16771 "Connection: Upgrade\r\n"
16772 "Upgrade: websocket\r\n"
16773 "Origin: http://www.example.org\r\n"
16774 "Sec-WebSocket-Version: 13\r\n"
16775 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416776 };
16777
16778 // The proxy responds to the connect with a 407, using a persistent
16779 // connection.
16780 MockRead data_reads[] = {
16781 // No credentials.
16782 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16783 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416784 MockRead("Content-Length: 0\r\n"),
16785 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416786
16787 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16788
16789 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16790 MockRead("Upgrade: websocket\r\n"),
16791 MockRead("Connection: Upgrade\r\n"),
16792 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16793 };
16794
16795 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16796 arraysize(data_writes));
16797 session_deps_.socket_factory->AddSocketDataProvider(&data);
16798 SSLSocketDataProvider ssl(ASYNC, OK);
16799 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16800
bnc87dcefc2017-05-25 12:47:5816801 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916802 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416803 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16804 trans->SetWebSocketHandshakeStreamCreateHelper(
16805 &websocket_stream_create_helper);
16806
16807 {
16808 TestCompletionCallback callback;
16809
tfarina42834112016-09-22 13:38:2016810 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416812
16813 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116814 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416815 }
16816
16817 const HttpResponseInfo* response = trans->GetResponseInfo();
16818 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216819 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416820 EXPECT_EQ(407, response->headers->response_code());
16821
16822 {
16823 TestCompletionCallback callback;
16824
16825 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16826 callback.callback());
robpercival214763f2016-07-01 23:27:0116827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416828
16829 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116830 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416831 }
16832
16833 response = trans->GetResponseInfo();
16834 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216835 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416836
16837 EXPECT_EQ(101, response->headers->response_code());
16838
16839 trans.reset();
16840 session->CloseAllConnections();
16841}
16842
16843// Verify that proxy headers are not sent to the destination server when
16844// establishing a tunnel for an insecure WebSocket connection.
16845// This requires the authentication info to be injected into the auth cache
16846// due to crbug.com/395064
16847// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116848TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416849 HttpRequestInfo request;
16850 request.method = "GET";
bncce36dca22015-04-21 22:11:2316851 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416852 AddWebSocketHeaders(&request.extra_headers);
16853
16854 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916855 session_deps_.proxy_resolution_service =
16856 ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416857
danakj1fd259a02016-04-16 03:17:0916858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416859
16860 MockWrite data_writes[] = {
16861 // Try to establish a tunnel for the WebSocket connection, with
16862 // credentials. Because WebSockets have a separate set of socket pools,
16863 // they cannot and will not use the same TCP/IP connection as the
16864 // preflight HTTP request.
16865 MockWrite(
bncce36dca22015-04-21 22:11:2316866 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16867 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416868 "Proxy-Connection: keep-alive\r\n"
16869 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16870
16871 MockWrite(
16872 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316873 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416874 "Connection: Upgrade\r\n"
16875 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316876 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416877 "Sec-WebSocket-Version: 13\r\n"
16878 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16879 };
16880
16881 MockRead data_reads[] = {
16882 // HTTP CONNECT with credentials.
16883 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16884
16885 // WebSocket connection established inside tunnel.
16886 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16887 MockRead("Upgrade: websocket\r\n"),
16888 MockRead("Connection: Upgrade\r\n"),
16889 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16890 };
16891
16892 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16893 arraysize(data_writes));
16894 session_deps_.socket_factory->AddSocketDataProvider(&data);
16895
16896 session->http_auth_cache()->Add(
16897 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16898 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16899
bnc87dcefc2017-05-25 12:47:5816900 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916901 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416902 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16903 trans->SetWebSocketHandshakeStreamCreateHelper(
16904 &websocket_stream_create_helper);
16905
16906 TestCompletionCallback callback;
16907
tfarina42834112016-09-22 13:38:2016908 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416910
16911 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116912 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416913
16914 const HttpResponseInfo* response = trans->GetResponseInfo();
16915 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216916 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416917
16918 EXPECT_EQ(101, response->headers->response_code());
16919
16920 trans.reset();
16921 session->CloseAllConnections();
16922}
16923
Bence Békydca6bd92018-01-30 13:43:0616924#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
16925
bncd16676a2016-07-20 16:23:0116926TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916927 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216928 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916929 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216930 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216931
16932 HttpRequestInfo request;
16933 request.method = "POST";
16934 request.url = GURL("http://www.foo.com/");
16935 request.upload_data_stream = &upload_data_stream;
16936
danakj1fd259a02016-04-16 03:17:0916937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616938 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216939 MockWrite data_writes[] = {
16940 MockWrite("POST / HTTP/1.1\r\n"
16941 "Host: www.foo.com\r\n"
16942 "Connection: keep-alive\r\n"
16943 "Content-Length: 3\r\n\r\n"),
16944 MockWrite("foo"),
16945 };
16946
16947 MockRead data_reads[] = {
16948 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16949 MockRead(SYNCHRONOUS, OK),
16950 };
16951 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16952 arraysize(data_writes));
16953 session_deps_.socket_factory->AddSocketDataProvider(&data);
16954
16955 TestCompletionCallback callback;
16956
16957 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016958 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116959 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216960
16961 std::string response_data;
bnc691fda62016-08-12 00:43:1616962 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216963
16964 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616965 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216966 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616967 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216968}
16969
bncd16676a2016-07-20 16:23:0116970TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916971 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216972 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916973 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216974 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216975
16976 HttpRequestInfo request;
16977 request.method = "POST";
16978 request.url = GURL("http://www.foo.com/");
16979 request.upload_data_stream = &upload_data_stream;
16980
danakj1fd259a02016-04-16 03:17:0916981 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216983 MockWrite data_writes[] = {
16984 MockWrite("POST / HTTP/1.1\r\n"
16985 "Host: www.foo.com\r\n"
16986 "Connection: keep-alive\r\n"
16987 "Content-Length: 3\r\n\r\n"),
16988 MockWrite("foo"),
16989 };
16990
16991 MockRead data_reads[] = {
16992 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16993 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16994 MockRead(SYNCHRONOUS, OK),
16995 };
16996 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16997 arraysize(data_writes));
16998 session_deps_.socket_factory->AddSocketDataProvider(&data);
16999
17000 TestCompletionCallback callback;
17001
17002 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017003 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117004 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217005
17006 std::string response_data;
bnc691fda62016-08-12 00:43:1617007 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217008
17009 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617010 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217011 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617012 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217013}
17014
bncd16676a2016-07-20 16:23:0117015TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217016 ChunkedUploadDataStream upload_data_stream(0);
17017
17018 HttpRequestInfo request;
17019 request.method = "POST";
17020 request.url = GURL("http://www.foo.com/");
17021 request.upload_data_stream = &upload_data_stream;
17022
danakj1fd259a02016-04-16 03:17:0917023 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617024 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217025 // Send headers successfully, but get an error while sending the body.
17026 MockWrite data_writes[] = {
17027 MockWrite("POST / HTTP/1.1\r\n"
17028 "Host: www.foo.com\r\n"
17029 "Connection: keep-alive\r\n"
17030 "Transfer-Encoding: chunked\r\n\r\n"),
17031 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17032 };
17033
17034 MockRead data_reads[] = {
17035 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17036 MockRead(SYNCHRONOUS, OK),
17037 };
17038 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17039 arraysize(data_writes));
17040 session_deps_.socket_factory->AddSocketDataProvider(&data);
17041
17042 TestCompletionCallback callback;
17043
17044 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017045 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217046
17047 base::RunLoop().RunUntilIdle();
17048 upload_data_stream.AppendData("f", 1, false);
17049
17050 base::RunLoop().RunUntilIdle();
17051 upload_data_stream.AppendData("oo", 2, true);
17052
robpercival214763f2016-07-01 23:27:0117053 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217054
17055 std::string response_data;
bnc691fda62016-08-12 00:43:1617056 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217057
17058 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1617059 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2217060 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1617061 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217062}
17063
rdsmith1d343be52016-10-21 20:37:5017064// Confirm that transactions whose throttle is created in (and stays in)
17065// the unthrottled state are not blocked.
17066TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
17067 TestNetworkStreamThrottler* throttler(nullptr);
17068 std::unique_ptr<HttpNetworkSession> session(
17069 CreateSessionWithThrottler(&session_deps_, &throttler));
17070
17071 // Send a simple request and make sure it goes through.
17072 HttpRequestInfo request;
17073 request.method = "GET";
17074 request.url = GURL("http://www.example.org/");
17075
bnc87dcefc2017-05-25 12:47:5817076 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917077 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017078
17079 MockWrite data_writes[] = {
17080 MockWrite("GET / HTTP/1.1\r\n"
17081 "Host: www.example.org\r\n"
17082 "Connection: keep-alive\r\n\r\n"),
17083 };
17084 MockRead data_reads[] = {
17085 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17086 MockRead(SYNCHRONOUS, OK),
17087 };
17088 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17089 arraysize(data_writes));
17090 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17091
17092 TestCompletionCallback callback;
17093 trans->Start(&request, callback.callback(), NetLogWithSource());
17094 EXPECT_EQ(OK, callback.WaitForResult());
17095}
17096
17097// Confirm requests can be blocked by a throttler, and are resumed
17098// when the throttle is unblocked.
17099TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
17100 TestNetworkStreamThrottler* throttler(nullptr);
17101 std::unique_ptr<HttpNetworkSession> session(
17102 CreateSessionWithThrottler(&session_deps_, &throttler));
17103
17104 // Send a simple request and make sure it goes through.
17105 HttpRequestInfo request;
17106 request.method = "GET";
17107 request.url = GURL("http://www.example.org/");
17108
17109 MockWrite data_writes[] = {
17110 MockWrite("GET / HTTP/1.1\r\n"
17111 "Host: www.example.org\r\n"
17112 "Connection: keep-alive\r\n\r\n"),
17113 };
17114 MockRead data_reads[] = {
17115 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17116 MockRead(SYNCHRONOUS, OK),
17117 };
17118 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17119 arraysize(data_writes));
17120 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17121
17122 // Start a request that will be throttled at start; confirm it
17123 // doesn't complete.
17124 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817125 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917126 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017127
17128 TestCompletionCallback callback;
17129 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17130 EXPECT_EQ(ERR_IO_PENDING, rv);
17131
17132 base::RunLoop().RunUntilIdle();
17133 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17134 EXPECT_FALSE(callback.have_result());
17135
17136 // Confirm the request goes on to complete when unthrottled.
17137 throttler->UnthrottleAllRequests();
17138 base::RunLoop().RunUntilIdle();
17139 ASSERT_TRUE(callback.have_result());
17140 EXPECT_EQ(OK, callback.WaitForResult());
17141}
17142
17143// Destroy a request while it's throttled.
17144TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
17145 TestNetworkStreamThrottler* throttler(nullptr);
17146 std::unique_ptr<HttpNetworkSession> session(
17147 CreateSessionWithThrottler(&session_deps_, &throttler));
17148
17149 // Send a simple request and make sure it goes through.
17150 HttpRequestInfo request;
17151 request.method = "GET";
17152 request.url = GURL("http://www.example.org/");
17153
17154 MockWrite data_writes[] = {
17155 MockWrite("GET / HTTP/1.1\r\n"
17156 "Host: www.example.org\r\n"
17157 "Connection: keep-alive\r\n\r\n"),
17158 };
17159 MockRead data_reads[] = {
17160 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17161 MockRead(SYNCHRONOUS, OK),
17162 };
17163 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17164 arraysize(data_writes));
17165 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17166
17167 // Start a request that will be throttled at start; confirm it
17168 // doesn't complete.
17169 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817170 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917171 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017172
17173 TestCompletionCallback callback;
17174 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17175 EXPECT_EQ(ERR_IO_PENDING, rv);
17176
17177 base::RunLoop().RunUntilIdle();
17178 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17179 EXPECT_FALSE(callback.have_result());
17180
17181 EXPECT_EQ(1u, throttler->num_outstanding_requests());
17182 trans.reset();
17183 EXPECT_EQ(0u, throttler->num_outstanding_requests());
17184}
17185
17186// Confirm the throttler receives SetPriority calls.
17187TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
17188 TestNetworkStreamThrottler* throttler(nullptr);
17189 std::unique_ptr<HttpNetworkSession> session(
17190 CreateSessionWithThrottler(&session_deps_, &throttler));
17191
17192 // Send a simple request and make sure it goes through.
17193 HttpRequestInfo request;
17194 request.method = "GET";
17195 request.url = GURL("http://www.example.org/");
17196
17197 MockWrite data_writes[] = {
17198 MockWrite("GET / HTTP/1.1\r\n"
17199 "Host: www.example.org\r\n"
17200 "Connection: keep-alive\r\n\r\n"),
17201 };
17202 MockRead data_reads[] = {
17203 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17204 MockRead(SYNCHRONOUS, OK),
17205 };
17206 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17207 arraysize(data_writes));
17208 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17209
17210 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1917211 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5017212 // Start the transaction to associate a throttle with it.
17213 TestCompletionCallback callback;
17214 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17215 EXPECT_EQ(ERR_IO_PENDING, rv);
17216
17217 EXPECT_EQ(0, throttler->num_set_priority_calls());
17218 trans->SetPriority(LOW);
17219 EXPECT_EQ(1, throttler->num_set_priority_calls());
17220 EXPECT_EQ(LOW, throttler->last_priority_set());
17221
17222 throttler->UnthrottleAllRequests();
17223 base::RunLoop().RunUntilIdle();
17224 ASSERT_TRUE(callback.have_result());
17225 EXPECT_EQ(OK, callback.WaitForResult());
17226}
17227
17228// Confirm that unthrottling from a SetPriority call by the
17229// throttler works properly.
17230TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
17231 TestNetworkStreamThrottler* throttler(nullptr);
17232 std::unique_ptr<HttpNetworkSession> session(
17233 CreateSessionWithThrottler(&session_deps_, &throttler));
17234
17235 // Send a simple request and make sure it goes through.
17236 HttpRequestInfo request;
17237 request.method = "GET";
17238 request.url = GURL("http://www.example.org/");
17239
17240 MockWrite data_writes[] = {
17241 MockWrite("GET / HTTP/1.1\r\n"
17242 "Host: www.example.org\r\n"
17243 "Connection: keep-alive\r\n\r\n"),
17244 };
17245 MockRead data_reads[] = {
17246 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17247 MockRead(SYNCHRONOUS, OK),
17248 };
17249 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17250 arraysize(data_writes));
17251 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17252
17253 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17254 data_writes, arraysize(data_writes));
17255 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17256
17257 // Start a request that will be throttled at start; confirm it
17258 // doesn't complete.
17259 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817260 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917261 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017262
17263 TestCompletionCallback callback;
17264 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17265 EXPECT_EQ(ERR_IO_PENDING, rv);
17266
17267 base::RunLoop().RunUntilIdle();
17268 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17269 EXPECT_FALSE(callback.have_result());
17270
17271 // Create a new request, call SetPriority on it to unthrottle,
17272 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1917273 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5017274 throttler->set_priority_change_closure(
17275 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17276 base::Unretained(throttler)));
17277
17278 // Start the transaction to associate a throttle with it.
17279 TestCompletionCallback callback1;
17280 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17281 EXPECT_EQ(ERR_IO_PENDING, rv);
17282
17283 trans1->SetPriority(IDLE);
17284
17285 base::RunLoop().RunUntilIdle();
17286 ASSERT_TRUE(callback.have_result());
17287 EXPECT_EQ(OK, callback.WaitForResult());
17288 ASSERT_TRUE(callback1.have_result());
17289 EXPECT_EQ(OK, callback1.WaitForResult());
17290}
17291
17292// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817293void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017294
17295// Confirm that destroying a transaction from a SetPriority call by the
17296// throttler works properly.
17297TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17298 TestNetworkStreamThrottler* throttler(nullptr);
17299 std::unique_ptr<HttpNetworkSession> session(
17300 CreateSessionWithThrottler(&session_deps_, &throttler));
17301
17302 // Send a simple request and make sure it goes through.
17303 HttpRequestInfo request;
17304 request.method = "GET";
17305 request.url = GURL("http://www.example.org/");
17306
17307 MockWrite data_writes[] = {
17308 MockWrite("GET / HTTP/1.1\r\n"
17309 "Host: www.example.org\r\n"
17310 "Connection: keep-alive\r\n\r\n"),
17311 };
17312 MockRead data_reads[] = {
17313 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17314 MockRead(SYNCHRONOUS, OK),
17315 };
17316 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17317 arraysize(data_writes));
17318 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17319
17320 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17321 data_writes, arraysize(data_writes));
17322 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17323
17324 // Start a request that will be throttled at start; confirm it
17325 // doesn't complete.
17326 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817327 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917328 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017329
17330 TestCompletionCallback callback;
17331 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17332 EXPECT_EQ(ERR_IO_PENDING, rv);
17333
17334 base::RunLoop().RunUntilIdle();
17335 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17336 EXPECT_FALSE(callback.have_result());
17337
17338 // Arrange for the set priority call on the above transaction to delete
17339 // the transaction.
bnc87dcefc2017-05-25 12:47:5817340 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017341 throttler->set_priority_change_closure(
17342 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17343
17344 // Call it and check results (partially a "doesn't crash" test).
17345 trans_ptr->SetPriority(IDLE);
17346 trans_ptr = nullptr; // No longer a valid pointer.
17347
17348 base::RunLoop().RunUntilIdle();
17349 ASSERT_FALSE(callback.have_result());
17350}
17351
nharperb7441ef2016-01-25 23:54:1417352#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117353TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417354 const std::string https_url = "https://www.example.com";
17355 HttpRequestInfo request;
17356 request.url = GURL(https_url);
17357 request.method = "GET";
17358
17359 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917360 ssl.ssl_info.token_binding_negotiated = true;
17361 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617362 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17364
bnc42331402016-07-25 13:36:1517365 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117366 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17367 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417368 MockRead(ASYNC, ERR_IO_PENDING)};
17369 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17370 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817371 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917372 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417374
17375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17376 TestCompletionCallback callback;
17377 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017378 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017379
17380 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417381
17382 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17383 HttpRequestHeaders headers;
17384 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17385 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17386}
17387#endif // !defined(OS_IOS)
17388
eustasc7d27da2017-04-06 10:33:2017389void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17390 const std::string& accept_encoding,
17391 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317392 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017393 bool should_match) {
17394 HttpRequestInfo request;
17395 request.method = "GET";
17396 request.url = GURL("http://www.foo.com/");
17397 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17398 accept_encoding);
17399
17400 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17401 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17402 // Send headers successfully, but get an error while sending the body.
17403 MockWrite data_writes[] = {
17404 MockWrite("GET / HTTP/1.1\r\n"
17405 "Host: www.foo.com\r\n"
17406 "Connection: keep-alive\r\n"
17407 "Accept-Encoding: "),
17408 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17409 };
17410
sky50576f32017-05-01 19:28:0317411 std::string response_code = "200 OK";
17412 std::string extra;
17413 if (!location.empty()) {
17414 response_code = "301 Redirect\r\nLocation: ";
17415 response_code.append(location);
17416 }
17417
eustasc7d27da2017-04-06 10:33:2017418 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317419 MockRead("HTTP/1.0 "),
17420 MockRead(response_code.data()),
17421 MockRead("\r\nContent-Encoding: "),
17422 MockRead(content_encoding.data()),
17423 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017424 MockRead(SYNCHRONOUS, OK),
17425 };
17426 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17427 arraysize(data_writes));
17428 session_deps->socket_factory->AddSocketDataProvider(&data);
17429
17430 TestCompletionCallback callback;
17431
17432 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17434
17435 rv = callback.WaitForResult();
17436 if (should_match) {
17437 EXPECT_THAT(rv, IsOk());
17438 } else {
17439 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17440 }
17441}
17442
17443TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317444 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017445}
17446
17447TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317448 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17449 true);
eustasc7d27da2017-04-06 10:33:2017450}
17451
17452TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17453 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317454 "", false);
17455}
17456
17457TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17458 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17459 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017460}
17461
xunjieli96f2a402017-06-05 17:24:2717462TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17463 ProxyConfig proxy_config;
17464 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17465 proxy_config.set_pac_mandatory(true);
17466 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917467 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Jeremy Roman0579ed62017-08-29 15:56:1917468 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
Bence Béky8f9d7d3952017-10-09 19:58:0417469 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717470
17471 HttpRequestInfo request;
17472 request.method = "GET";
17473 request.url = GURL("http://www.example.org/");
17474
17475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17477
17478 TestCompletionCallback callback;
17479
17480 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17482 EXPECT_THAT(callback.WaitForResult(),
17483 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17484}
17485
17486TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17487 ProxyConfig proxy_config;
17488 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17489 proxy_config.set_pac_mandatory(true);
17490 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17491 new MockAsyncProxyResolverFactory(false);
17492 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917493 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
17494 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
17495 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717496 HttpRequestInfo request;
17497 request.method = "GET";
17498 request.url = GURL("http://www.example.org/");
17499
17500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17501 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17502
17503 TestCompletionCallback callback;
17504 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17506
17507 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17508 ERR_FAILED, &resolver);
17509 EXPECT_THAT(callback.WaitForResult(),
17510 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17511}
17512
17513TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917514 session_deps_.proxy_resolution_service =
17515 ProxyResolutionService::CreateFixedFromPacResult("QUIC myproxy.org:443");
xunjieli96f2a402017-06-05 17:24:2717516 session_deps_.enable_quic = false;
17517 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17518
17519 HttpRequestInfo request;
17520 request.method = "GET";
17521 request.url = GURL("http://www.example.org/");
17522
17523 TestCompletionCallback callback;
17524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17525 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17526 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17527
17528 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17529}
17530
[email protected]89ceba9a2009-03-21 03:46:0617531} // namespace net