blob: b25862184046b7b299f9d3240ea2d0eaf5453721 [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"
[email protected]ac790b42009-12-02 04:31:3140#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5241#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1542#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0643#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2144#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1145#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1646#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5347#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2448#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1249#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0050#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2951#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1952#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2453#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5754#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5255#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5656#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2457#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1358#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5359#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5760#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3861#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2462#include "net/http/http_stream_parser.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"
sammc5dd160c2015-04-02 02:43:1370#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5371#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0372#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1173#include "net/proxy/proxy_resolver.h"
xunjieli96f2a402017-06-05 17:24:2774#include "net/proxy/proxy_resolver_factory.h"
tbansal28e68f82016-02-04 02:56:1575#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1176#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4477#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1578#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0379#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4780#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0281#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0782#include "net/socket/next_proto.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]831e4a32013-11-14 02:14:4499#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:18100#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52101#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15102#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27103#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52104
robpercival214763f2016-07-01 23:27:01105using net::test::IsError;
106using net::test::IsOk;
107
[email protected]ad65a3e2013-12-25 18:18:01108using base::ASCIIToUTF16;
109
initial.commit586acc5fe2008-07-26 22:42:52110//-----------------------------------------------------------------------------
111
ttuttle859dc7a2015-04-23 19:42:29112namespace net {
113
[email protected]13c8a092010-07-29 06:15:44114namespace {
115
rdsmith1d343be52016-10-21 20:37:50116class TestNetworkStreamThrottler : public NetworkThrottleManager {
117 public:
118 TestNetworkStreamThrottler()
119 : throttle_new_requests_(false),
120 num_set_priority_calls_(0),
121 last_priority_set_(IDLE) {}
122
123 ~TestNetworkStreamThrottler() override {
124 EXPECT_TRUE(outstanding_throttles_.empty());
125 }
126
127 // NetworkThrottleManager
128 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
129 RequestPriority priority,
130 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58131 auto test_throttle =
132 base::MakeUnique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50133 outstanding_throttles_.insert(test_throttle.get());
134 return std::move(test_throttle);
135 }
136
137 void UnthrottleAllRequests() {
138 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25139 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24140 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50141 throttle->Unthrottle();
142 }
143 }
144
145 void set_throttle_new_requests(bool throttle_new_requests) {
146 throttle_new_requests_ = throttle_new_requests;
147 }
148
149 // Includes both throttled and unthrottled throttles.
150 size_t num_outstanding_requests() const {
151 return outstanding_throttles_.size();
152 }
153
154 int num_set_priority_calls() const { return num_set_priority_calls_; }
155 RequestPriority last_priority_set() const { return last_priority_set_; }
156 void set_priority_change_closure(
157 const base::Closure& priority_change_closure) {
158 priority_change_closure_ = priority_change_closure;
159 }
160
161 private:
162 class TestThrottle : public NetworkThrottleManager::Throttle {
163 public:
164 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
165
166 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24167 bool IsBlocked() const override { return throttled_; }
168 RequestPriority Priority() const override {
169 NOTREACHED();
170 return IDLE;
171 }
rdsmith1d343be52016-10-21 20:37:50172 void SetPriority(RequestPriority priority) override {
173 throttler_->SetPriorityCalled(priority);
174 }
175
176 TestThrottle(bool throttled,
177 ThrottleDelegate* delegate,
178 TestNetworkStreamThrottler* throttler)
179 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
180
181 void Unthrottle() {
182 EXPECT_TRUE(throttled_);
183
184 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24185 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50186 }
187
188 bool throttled_;
189 ThrottleDelegate* delegate_;
190 TestNetworkStreamThrottler* throttler_;
191 };
192
193 void OnThrottleDestroyed(TestThrottle* throttle) {
194 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
195 outstanding_throttles_.erase(throttle);
196 }
197
198 void SetPriorityCalled(RequestPriority priority) {
199 ++num_set_priority_calls_;
200 last_priority_set_ = priority;
201 if (!priority_change_closure_.is_null())
202 priority_change_closure_.Run();
203 }
204
205 // Includes both throttled and unthrottled throttles.
206 std::set<TestThrottle*> outstanding_throttles_;
207 bool throttle_new_requests_;
208 int num_set_priority_calls_;
209 RequestPriority last_priority_set_;
210 base::Closure priority_change_closure_;
211
212 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
213};
214
[email protected]42cba2fb2013-03-29 19:58:57215const base::string16 kBar(ASCIIToUTF16("bar"));
216const base::string16 kBar2(ASCIIToUTF16("bar2"));
217const base::string16 kBar3(ASCIIToUTF16("bar3"));
218const base::string16 kBaz(ASCIIToUTF16("baz"));
219const base::string16 kFirst(ASCIIToUTF16("first"));
220const base::string16 kFoo(ASCIIToUTF16("foo"));
221const base::string16 kFoo2(ASCIIToUTF16("foo2"));
222const base::string16 kFoo3(ASCIIToUTF16("foo3"));
223const base::string16 kFou(ASCIIToUTF16("fou"));
224const base::string16 kSecond(ASCIIToUTF16("second"));
225const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
226const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44227
bnc2df4b522016-07-08 18:17:43228const char kAlternativeServiceHttpHeader[] =
229 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
230
ttuttle859dc7a2015-04-23 19:42:29231int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
232 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
233 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02234}
235
ttuttle859dc7a2015-04-23 19:42:29236int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
237 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
238 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02239}
240
ttuttle859dc7a2015-04-23 19:42:29241bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
242 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
243 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52244}
245
[email protected]f3da152d2012-06-02 01:00:57246// Takes in a Value created from a NetLogHttpResponseParameter, and returns
247// a JSONified list of headers as a single string. Uses single quotes instead
248// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27249bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57250 if (!params)
251 return false;
[email protected]ea5ef4c2013-06-13 22:50:27252 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57253 if (!params->GetList("headers", &header_list))
254 return false;
255 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34256 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28257 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57258 return true;
259}
260
[email protected]029c83b62013-01-24 05:28:20261// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
262// used.
ttuttle859dc7a2015-04-23 19:42:29263void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20264 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19265 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25266
[email protected]029c83b62013-01-24 05:28:20267 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
268 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
269
ttuttle859dc7a2015-04-23 19:42:29270 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20271 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25272
273 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25274
[email protected]3b23a222013-05-15 21:33:25275 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25276 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
277 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25278 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25279}
280
[email protected]029c83b62013-01-24 05:28:20281// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
282// used.
ttuttle859dc7a2015-04-23 19:42:29283void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25284 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20285 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19286 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20287
288 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
289 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
290
ttuttle859dc7a2015-04-23 19:42:29291 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
292 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20293 EXPECT_LE(load_timing_info.connect_timing.connect_end,
294 load_timing_info.send_start);
295
296 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20297
[email protected]3b23a222013-05-15 21:33:25298 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20299 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
300 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25301 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20302}
303
304// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
305// used.
ttuttle859dc7a2015-04-23 19:42:29306void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20307 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19308 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20309
ttuttle859dc7a2015-04-23 19:42:29310 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20311
312 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
313 EXPECT_LE(load_timing_info.proxy_resolve_start,
314 load_timing_info.proxy_resolve_end);
315 EXPECT_LE(load_timing_info.proxy_resolve_end,
316 load_timing_info.send_start);
317 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20318
[email protected]3b23a222013-05-15 21:33:25319 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20320 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
321 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25322 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20323}
324
325// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
326// used.
ttuttle859dc7a2015-04-23 19:42:29327void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20328 int connect_timing_flags) {
329 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19330 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20331
332 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
333 EXPECT_LE(load_timing_info.proxy_resolve_start,
334 load_timing_info.proxy_resolve_end);
335 EXPECT_LE(load_timing_info.proxy_resolve_end,
336 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29337 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
338 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20339 EXPECT_LE(load_timing_info.connect_timing.connect_end,
340 load_timing_info.send_start);
341
342 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20343
[email protected]3b23a222013-05-15 21:33:25344 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20345 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
346 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25347 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25348}
349
ttuttle859dc7a2015-04-23 19:42:29350void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24351 headers->SetHeader("Connection", "Upgrade");
352 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23353 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24354 headers->SetHeader("Sec-WebSocket-Version", "13");
355 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
356}
357
danakj1fd259a02016-04-16 03:17:09358std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42359 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34360 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14361}
362
rdsmith1d343be52016-10-21 20:37:50363// Note that the pointer written into |*throttler| will only be valid
364// for the lifetime of the returned HttpNetworkSession.
365std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
366 SpdySessionDependencies* session_deps,
367 TestNetworkStreamThrottler** throttler) {
368 std::unique_ptr<HttpNetworkSession> session(
369 SpdySessionDependencies::SpdyCreateSession(session_deps));
370
bnc87dcefc2017-05-25 12:47:58371 auto owned_throttler = base::MakeUnique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50372 *throttler = owned_throttler.get();
373
374 HttpNetworkSessionPeer peer(session.get());
375 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
376
377 return session;
378}
379
xunjieli96f2a402017-06-05 17:24:27380class FailingProxyResolverFactory : public ProxyResolverFactory {
381 public:
382 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
383
384 // ProxyResolverFactory override.
385 int CreateProxyResolver(
386 const scoped_refptr<ProxyResolverScriptData>& script_data,
387 std::unique_ptr<ProxyResolver>* result,
388 const CompletionCallback& callback,
389 std::unique_ptr<Request>* request) override {
390 return ERR_PAC_SCRIPT_FAILED;
391 }
392};
393
[email protected]448d4ca52012-03-04 04:12:23394} // namespace
395
bncd16676a2016-07-20 16:23:01396class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03397 public:
bncd16676a2016-07-20 16:23:01398 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03399 // Important to restore the per-pool limit first, since the pool limit must
400 // always be greater than group limit, and the tests reduce both limits.
401 ClientSocketPoolManager::set_max_sockets_per_pool(
402 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
403 ClientSocketPoolManager::set_max_sockets_per_group(
404 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
405 }
406
[email protected]e3ceb682011-06-28 23:55:46407 protected:
[email protected]23e482282013-06-14 16:08:02408 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15409 : ssl_(ASYNC, OK),
410 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03411 HttpNetworkSession::NORMAL_SOCKET_POOL)),
412 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
413 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28414 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03415 }
[email protected]bb88e1d32013-05-03 23:11:07416
[email protected]e3ceb682011-06-28 23:55:46417 struct SimpleGetHelperResult {
418 int rv;
419 std::string status_line;
420 std::string response_data;
sclittlefb249892015-09-10 21:33:22421 int64_t total_received_bytes;
422 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25423 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47424 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59425 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46426 };
427
dcheng67be2b1f2014-10-27 21:47:29428 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50429 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55430 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54431 }
432
dcheng67be2b1f2014-10-27 21:47:29433 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50434 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55435 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09436 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55437 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09438 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50439 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55440 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09441 }
442
[email protected]202965992011-12-07 23:04:51443 // Either |write_failure| specifies a write failure or |read_failure|
444 // specifies a read failure when using a reused socket. In either case, the
445 // failure should cause the network transaction to resend the request, and the
446 // other argument should be NULL.
447 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
448 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52449
[email protected]a34f61ee2014-03-18 20:59:49450 // Either |write_failure| specifies a write failure or |read_failure|
451 // specifies a read failure when using a reused socket. In either case, the
452 // failure should cause the network transaction to resend the request, and the
453 // other argument should be NULL.
454 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10455 const MockRead* read_failure,
456 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49457
[email protected]5a60c8b2011-10-19 20:14:29458 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
459 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15460 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52461
[email protected]ff007e162009-05-23 09:13:15462 HttpRequestInfo request;
463 request.method = "GET";
bncce36dca22015-04-21 22:11:23464 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52465
vishal.b62985ca92015-04-17 08:45:51466 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07467 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27470
[email protected]5a60c8b2011-10-19 20:14:29471 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07472 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29473 }
initial.commit586acc5fe2008-07-26 22:42:52474
[email protected]49639fa2011-12-20 23:22:41475 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52476
eroman24bc6a12015-05-06 19:55:48477 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16478 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52480
[email protected]ff007e162009-05-23 09:13:15481 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16482 out.total_received_bytes = trans.GetTotalReceivedBytes();
483 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25484
485 // Even in the failure cases that use this function, connections are always
486 // successfully established before the error.
bnc691fda62016-08-12 00:43:16487 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25488 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
489
[email protected]ff007e162009-05-23 09:13:15490 if (out.rv != OK)
491 return out;
492
bnc691fda62016-08-12 00:43:16493 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50494 // Can't use ASSERT_* inside helper functions like this, so
495 // return an error.
wezca1070932016-05-26 20:30:52496 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50497 out.rv = ERR_UNEXPECTED;
498 return out;
499 }
[email protected]ff007e162009-05-23 09:13:15500 out.status_line = response->headers->GetStatusLine();
501
[email protected]80a09a82012-11-16 17:40:06502 EXPECT_EQ("127.0.0.1", response->socket_address.host());
503 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19504
ttuttled9dbc652015-09-29 20:00:59505 bool got_endpoint =
bnc691fda62016-08-12 00:43:16506 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59507 EXPECT_EQ(got_endpoint,
508 out.remote_endpoint_after_start.address().size() > 0);
509
bnc691fda62016-08-12 00:43:16510 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01511 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40512
mmenke43758e62015-05-04 21:09:46513 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40514 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39515 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00516 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
517 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39518 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00519 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
520 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15521
[email protected]f3da152d2012-06-02 01:00:57522 std::string line;
523 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
524 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
525
[email protected]79e1fd62013-06-20 06:50:04526 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16527 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04528 std::string value;
529 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23530 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04531 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
532 EXPECT_EQ("keep-alive", value);
533
534 std::string response_headers;
535 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23536 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04537 response_headers);
[email protected]3deb9a52010-11-11 00:24:40538
bnc691fda62016-08-12 00:43:16539 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22540 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16541 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22542
bnc691fda62016-08-12 00:43:16543 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47544 return out;
[email protected]ff007e162009-05-23 09:13:15545 }
initial.commit586acc5fe2008-07-26 22:42:52546
[email protected]5a60c8b2011-10-19 20:14:29547 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
548 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22549 MockWrite data_writes[] = {
550 MockWrite("GET / HTTP/1.1\r\n"
551 "Host: www.example.org\r\n"
552 "Connection: keep-alive\r\n\r\n"),
553 };
[email protected]5a60c8b2011-10-19 20:14:29554
sclittlefb249892015-09-10 21:33:22555 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
556 arraysize(data_writes));
557 StaticSocketDataProvider* data[] = {&reads};
558 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
559
560 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
561 out.total_sent_bytes);
562 return out;
[email protected]b8015c42013-12-24 15:18:19563 }
564
bnc032658ba2016-09-26 18:17:15565 void AddSSLSocketData() {
566 ssl_.next_proto = kProtoHTTP2;
567 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
568 ASSERT_TRUE(ssl_.cert);
569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
570 }
571
[email protected]ff007e162009-05-23 09:13:15572 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
573 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52574
[email protected]ff007e162009-05-23 09:13:15575 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07576
577 void BypassHostCacheOnRefreshHelper(int load_flags);
578
579 void CheckErrorIsPassedBack(int error, IoMode mode);
580
[email protected]4bd46222013-05-14 19:32:23581 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07582 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15583 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03584
585 // Original socket limits. Some tests set these. Safest to always restore
586 // them once each test has been run.
587 int old_max_group_sockets_;
588 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15589};
[email protected]231d5a32008-09-13 00:45:27590
[email protected]448d4ca52012-03-04 04:12:23591namespace {
592
ryansturm49a8cb12016-06-15 16:51:09593class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27594 public:
ryansturm49a8cb12016-06-15 16:51:09595 BeforeHeadersSentHandler()
596 : observed_before_headers_sent_with_proxy_(false),
597 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27598
ryansturm49a8cb12016-06-15 16:51:09599 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
600 HttpRequestHeaders* request_headers) {
601 observed_before_headers_sent_ = true;
602 if (!proxy_info.is_http() && !proxy_info.is_https() &&
603 !proxy_info.is_quic()) {
604 return;
605 }
606 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27607 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
608 }
609
ryansturm49a8cb12016-06-15 16:51:09610 bool observed_before_headers_sent_with_proxy() const {
611 return observed_before_headers_sent_with_proxy_;
612 }
613
614 bool observed_before_headers_sent() const {
615 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27616 }
617
618 std::string observed_proxy_server_uri() const {
619 return observed_proxy_server_uri_;
620 }
621
622 private:
ryansturm49a8cb12016-06-15 16:51:09623 bool observed_before_headers_sent_with_proxy_;
624 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27625 std::string observed_proxy_server_uri_;
626
ryansturm49a8cb12016-06-15 16:51:09627 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27628};
629
[email protected]15a5ccf82008-10-23 19:57:43630// Fill |str| with a long header list that consumes >= |size| bytes.
631void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51632 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19633 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
634 const int sizeof_row = strlen(row);
635 const int num_rows = static_cast<int>(
636 ceil(static_cast<float>(size) / sizeof_row));
637 const int sizeof_data = num_rows * sizeof_row;
638 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43639 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51640
[email protected]4ddaf2502008-10-23 18:26:19641 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43642 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19643}
644
thakis84dff942015-07-28 20:47:38645#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29646// Alternative functions that eliminate randomness and dependency on the local
647// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14648void MockGenerateRandom1(uint8_t* output, size_t n) {
649 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
650 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29651 static size_t current_byte = 0;
652 for (size_t i = 0; i < n; ++i) {
653 output[i] = bytes[current_byte++];
654 current_byte %= arraysize(bytes);
655 }
656}
657
avibf0746c2015-12-09 19:53:14658void MockGenerateRandom2(uint8_t* output, size_t n) {
659 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
660 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
661 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29662 static size_t current_byte = 0;
663 for (size_t i = 0; i < n; ++i) {
664 output[i] = bytes[current_byte++];
665 current_byte %= arraysize(bytes);
666 }
667}
668
[email protected]fe2bc6a2009-03-23 16:52:20669std::string MockGetHostName() {
670 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29671}
thakis84dff942015-07-28 20:47:38672#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29673
[email protected]e60e47a2010-07-14 03:37:18674template<typename ParentPool>
675class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31676 public:
[email protected]9e1bdd32011-02-03 21:48:34677 CaptureGroupNameSocketPool(HostResolver* host_resolver,
678 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18679
[email protected]d80a4322009-08-14 07:07:49680 const std::string last_group_name_received() const {
681 return last_group_name_;
682 }
683
dmichaeld6e570d2014-12-18 22:30:57684 int RequestSocket(const std::string& group_name,
685 const void* socket_params,
686 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15687 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57688 ClientSocketHandle* handle,
689 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20690 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31691 last_group_name_ = group_name;
692 return ERR_IO_PENDING;
693 }
dmichaeld6e570d2014-12-18 22:30:57694 void CancelRequest(const std::string& group_name,
695 ClientSocketHandle* handle) override {}
696 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09697 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57698 int id) override {}
699 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23700 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57701 int IdleSocketCount() const override { return 0; }
702 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31703 return 0;
704 }
dmichaeld6e570d2014-12-18 22:30:57705 LoadState GetLoadState(const std::string& group_name,
706 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31707 return LOAD_STATE_IDLE;
708 }
dmichaeld6e570d2014-12-18 22:30:57709 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26710 return base::TimeDelta();
711 }
[email protected]d80a4322009-08-14 07:07:49712
713 private:
[email protected]04e5be32009-06-26 20:00:31714 std::string last_group_name_;
715};
716
[email protected]ab739042011-04-07 15:22:28717typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
718CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13719typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
720CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06721typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11722CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18723typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
724CaptureGroupNameSSLSocketPool;
725
rkaplowd90695c2015-03-25 22:12:41726template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18727CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34728 HostResolver* host_resolver,
729 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21730 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18731
hashimoto0d3e4fb2015-01-09 05:02:50732template <>
[email protected]2df19bb2010-08-25 20:13:46733CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21734 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34735 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09736 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46737
[email protected]007b3f82013-04-09 08:46:45738template <>
[email protected]e60e47a2010-07-14 03:37:18739CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21740 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34741 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45742 : SSLClientSocketPool(0,
743 0,
[email protected]007b3f82013-04-09 08:46:45744 cert_verifier,
745 NULL,
746 NULL,
[email protected]284303b62013-11-28 15:11:54747 NULL,
eranm6571b2b2014-12-03 15:53:23748 NULL,
[email protected]007b3f82013-04-09 08:46:45749 std::string(),
750 NULL,
751 NULL,
752 NULL,
753 NULL,
754 NULL,
[email protected]8e458552014-08-05 00:02:15755 NULL) {
756}
[email protected]2227c692010-05-04 15:36:11757
[email protected]231d5a32008-09-13 00:45:27758//-----------------------------------------------------------------------------
759
[email protected]79cb5c12011-09-12 13:12:04760// Helper functions for validating that AuthChallengeInfo's are correctly
761// configured for common cases.
762bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
763 if (!auth_challenge)
764 return false;
765 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43766 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04767 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19768 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04769 return true;
770}
771
772bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
773 if (!auth_challenge)
774 return false;
775 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43776 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
777 EXPECT_EQ("MyRealm1", auth_challenge->realm);
778 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
779 return true;
780}
781
782bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
783 if (!auth_challenge)
784 return false;
785 EXPECT_TRUE(auth_challenge->is_proxy);
786 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04787 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19788 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04789 return true;
790}
791
792bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
793 if (!auth_challenge)
794 return false;
795 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43796 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04797 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19798 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04799 return true;
800}
801
thakis84dff942015-07-28 20:47:38802#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04803bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
804 if (!auth_challenge)
805 return false;
806 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43807 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04808 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19809 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04810 return true;
811}
thakis84dff942015-07-28 20:47:38812#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04813
[email protected]448d4ca52012-03-04 04:12:23814} // namespace
815
bncd16676a2016-07-20 16:23:01816TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09817 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16818 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27819}
820
bncd16676a2016-07-20 16:23:01821TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27822 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35823 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
824 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06825 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27826 };
[email protected]31a2bfe2010-02-09 08:03:39827 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
828 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01829 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27830 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
831 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22832 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
833 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47834 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59835
836 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27837}
838
839// Response with no status line.
bncd16676a2016-07-20 16:23:01840TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27841 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35842 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06843 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27844 };
[email protected]31a2bfe2010-02-09 08:03:39845 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
846 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41847 EXPECT_THAT(out.rv, IsOk());
848 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
849 EXPECT_EQ("hello world", out.response_data);
850 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
851 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27852}
853
mmenkea7da6da2016-09-01 21:56:52854// Response with no status line, and a weird port. Should fail by default.
855TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
856 MockRead data_reads[] = {
857 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
858 };
859
860 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
861 session_deps_.socket_factory->AddSocketDataProvider(&data);
862
863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
864
krasinc06a72a2016-12-21 03:42:46865 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58866 auto trans =
867 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52868
mmenkea7da6da2016-09-01 21:56:52869 request.method = "GET";
870 request.url = GURL("http://www.example.com:2000/");
871 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20872 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52873 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
874}
875
876// Response with no status line, and a weird port. Option to allow weird ports
877// enabled.
878TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
879 MockRead data_reads[] = {
880 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
881 };
882
883 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
884 session_deps_.socket_factory->AddSocketDataProvider(&data);
885 session_deps_.http_09_on_non_default_ports_enabled = true;
886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
887
krasinc06a72a2016-12-21 03:42:46888 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58889 auto trans =
890 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52891
mmenkea7da6da2016-09-01 21:56:52892 request.method = "GET";
893 request.url = GURL("http://www.example.com:2000/");
894 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20895 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52896 EXPECT_THAT(callback.GetResult(rv), IsOk());
897
898 const HttpResponseInfo* info = trans->GetResponseInfo();
899 ASSERT_TRUE(info->headers);
900 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
901
902 // Don't bother to read the body - that's verified elsewhere, important thing
903 // is that the option to allow HTTP/0.9 on non-default ports is respected.
904}
905
[email protected]231d5a32008-09-13 00:45:27906// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01907TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27908 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35909 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06910 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27911 };
[email protected]31a2bfe2010-02-09 08:03:39912 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
913 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01914 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27915 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
916 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22917 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
918 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27919}
920
921// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01922TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27923 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35924 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06925 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27926 };
[email protected]31a2bfe2010-02-09 08:03:39927 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
928 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01929 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27930 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
931 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22932 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
933 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27934}
935
936// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01937TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27938 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35939 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06940 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27941 };
[email protected]31a2bfe2010-02-09 08:03:39942 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
943 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41944 EXPECT_THAT(out.rv, IsOk());
945 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
946 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
947 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
948 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27949}
950
951// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01952TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27953 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35954 MockRead("\n"),
955 MockRead("\n"),
956 MockRead("Q"),
957 MockRead("J"),
958 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06959 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27960 };
[email protected]31a2bfe2010-02-09 08:03:39961 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
962 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01963 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27964 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
965 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22966 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
967 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27968}
969
970// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01971TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27972 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35973 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06974 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27975 };
[email protected]31a2bfe2010-02-09 08:03:39976 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
977 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41978 EXPECT_THAT(out.rv, IsOk());
979 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
980 EXPECT_EQ("HTT", out.response_data);
981 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
982 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52983}
984
[email protected]f9d44aa2008-09-23 23:57:17985// Simulate a 204 response, lacking a Content-Length header, sent over a
986// persistent connection. The response should still terminate since a 204
987// cannot have a response body.
bncd16676a2016-07-20 16:23:01988TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19989 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17990 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35991 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19992 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06993 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17994 };
[email protected]31a2bfe2010-02-09 08:03:39995 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
996 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01997 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17998 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
999 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221000 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1001 int64_t response_size = reads_size - strlen(junk);
1002 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171003}
1004
[email protected]0877e3d2009-10-17 22:29:571005// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011006TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191007 std::string final_chunk = "0\r\n\r\n";
1008 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1009 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571010 MockRead data_reads[] = {
1011 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1012 MockRead("5\r\nHello\r\n"),
1013 MockRead("1\r\n"),
1014 MockRead(" \r\n"),
1015 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191016 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061017 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571018 };
[email protected]31a2bfe2010-02-09 08:03:391019 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1020 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011021 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571022 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1023 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221024 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1025 int64_t response_size = reads_size - extra_data.size();
1026 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571027}
1028
[email protected]9fe44f52010-09-23 18:36:001029// Next tests deal with http://crbug.com/56344.
1030
bncd16676a2016-07-20 16:23:011031TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001032 MultipleContentLengthHeadersNoTransferEncoding) {
1033 MockRead data_reads[] = {
1034 MockRead("HTTP/1.1 200 OK\r\n"),
1035 MockRead("Content-Length: 10\r\n"),
1036 MockRead("Content-Length: 5\r\n\r\n"),
1037 };
1038 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1039 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011040 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001041}
1042
bncd16676a2016-07-20 16:23:011043TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041044 DuplicateContentLengthHeadersNoTransferEncoding) {
1045 MockRead data_reads[] = {
1046 MockRead("HTTP/1.1 200 OK\r\n"),
1047 MockRead("Content-Length: 5\r\n"),
1048 MockRead("Content-Length: 5\r\n\r\n"),
1049 MockRead("Hello"),
1050 };
1051 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1052 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011053 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041054 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1055 EXPECT_EQ("Hello", out.response_data);
1056}
1057
bncd16676a2016-07-20 16:23:011058TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041059 ComplexContentLengthHeadersNoTransferEncoding) {
1060 // More than 2 dupes.
1061 {
1062 MockRead data_reads[] = {
1063 MockRead("HTTP/1.1 200 OK\r\n"),
1064 MockRead("Content-Length: 5\r\n"),
1065 MockRead("Content-Length: 5\r\n"),
1066 MockRead("Content-Length: 5\r\n\r\n"),
1067 MockRead("Hello"),
1068 };
1069 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1070 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011071 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041072 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1073 EXPECT_EQ("Hello", out.response_data);
1074 }
1075 // HTTP/1.0
1076 {
1077 MockRead data_reads[] = {
1078 MockRead("HTTP/1.0 200 OK\r\n"),
1079 MockRead("Content-Length: 5\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n\r\n"),
1082 MockRead("Hello"),
1083 };
1084 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1085 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011086 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041087 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1088 EXPECT_EQ("Hello", out.response_data);
1089 }
1090 // 2 dupes and one mismatched.
1091 {
1092 MockRead data_reads[] = {
1093 MockRead("HTTP/1.1 200 OK\r\n"),
1094 MockRead("Content-Length: 10\r\n"),
1095 MockRead("Content-Length: 10\r\n"),
1096 MockRead("Content-Length: 5\r\n\r\n"),
1097 };
1098 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1099 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011100 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041101 }
1102}
1103
bncd16676a2016-07-20 16:23:011104TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001105 MultipleContentLengthHeadersTransferEncoding) {
1106 MockRead data_reads[] = {
1107 MockRead("HTTP/1.1 200 OK\r\n"),
1108 MockRead("Content-Length: 666\r\n"),
1109 MockRead("Content-Length: 1337\r\n"),
1110 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1111 MockRead("5\r\nHello\r\n"),
1112 MockRead("1\r\n"),
1113 MockRead(" \r\n"),
1114 MockRead("5\r\nworld\r\n"),
1115 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061116 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001117 };
1118 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1119 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011120 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001121 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1122 EXPECT_EQ("Hello world", out.response_data);
1123}
1124
[email protected]1628fe92011-10-04 23:04:551125// Next tests deal with http://crbug.com/98895.
1126
1127// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011128TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551129 MockRead data_reads[] = {
1130 MockRead("HTTP/1.1 200 OK\r\n"),
1131 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1132 MockRead("Content-Length: 5\r\n\r\n"),
1133 MockRead("Hello"),
1134 };
1135 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1136 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011137 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551138 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1139 EXPECT_EQ("Hello", out.response_data);
1140}
1141
[email protected]54a9c6e52012-03-21 20:10:591142// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011143TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551144 MockRead data_reads[] = {
1145 MockRead("HTTP/1.1 200 OK\r\n"),
1146 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1147 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1148 MockRead("Content-Length: 5\r\n\r\n"),
1149 MockRead("Hello"),
1150 };
1151 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1152 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011153 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591154 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1155 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551156}
1157
1158// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011159TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551160 MockRead data_reads[] = {
1161 MockRead("HTTP/1.1 200 OK\r\n"),
1162 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1163 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1164 MockRead("Content-Length: 5\r\n\r\n"),
1165 MockRead("Hello"),
1166 };
1167 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1168 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011169 EXPECT_THAT(out.rv,
1170 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551171}
1172
[email protected]54a9c6e52012-03-21 20:10:591173// Checks that two identical Location headers result in no error.
1174// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011175TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551176 MockRead data_reads[] = {
1177 MockRead("HTTP/1.1 302 Redirect\r\n"),
1178 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591179 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551180 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061181 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551182 };
1183
1184 HttpRequestInfo request;
1185 request.method = "GET";
1186 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551187
danakj1fd259a02016-04-16 03:17:091188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161189 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551190
1191 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071192 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551193
[email protected]49639fa2011-12-20 23:22:411194 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551195
tfarina42834112016-09-22 13:38:201196 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551198
robpercival214763f2016-07-01 23:27:011199 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551200
bnc691fda62016-08-12 00:43:161201 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521202 ASSERT_TRUE(response);
1203 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551204 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1205 std::string url;
1206 EXPECT_TRUE(response->headers->IsRedirect(&url));
1207 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471208 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551209}
1210
[email protected]1628fe92011-10-04 23:04:551211// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011212TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551213 MockRead data_reads[] = {
1214 MockRead("HTTP/1.1 302 Redirect\r\n"),
1215 MockRead("Location: http://good.com/\r\n"),
1216 MockRead("Location: http://evil.com/\r\n"),
1217 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061218 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551219 };
1220 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1221 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011222 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551223}
1224
[email protected]ef0faf2e72009-03-05 23:27:231225// Do a request using the HEAD method. Verify that we don't try to read the
1226// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011227TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421228 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231229 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231230 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231231
danakj1fd259a02016-04-16 03:17:091232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091234 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161235 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091236 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1237 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271238
[email protected]ef0faf2e72009-03-05 23:27:231239 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131240 MockWrite("HEAD / HTTP/1.1\r\n"
1241 "Host: www.example.org\r\n"
1242 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231243 };
1244 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231245 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1246 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231247
mmenked39192ee2015-12-09 00:57:231248 // No response body because the test stops reading here.
1249 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231250 };
1251
[email protected]31a2bfe2010-02-09 08:03:391252 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1253 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071254 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231255
[email protected]49639fa2011-12-20 23:22:411256 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231257
tfarina42834112016-09-22 13:38:201258 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011259 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231260
1261 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011262 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231263
bnc691fda62016-08-12 00:43:161264 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521265 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231266
1267 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521268 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231269 EXPECT_EQ(1234, response->headers->GetContentLength());
1270 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471271 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091272 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1273 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231274
1275 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101276 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231277 bool has_server_header = response->headers->EnumerateHeader(
1278 &iter, "Server", &server_header);
1279 EXPECT_TRUE(has_server_header);
1280 EXPECT_EQ("Blah", server_header);
1281
1282 // Reading should give EOF right away, since there is no message body
1283 // (despite non-zero content-length).
1284 std::string response_data;
bnc691fda62016-08-12 00:43:161285 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011286 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231287 EXPECT_EQ("", response_data);
1288}
1289
bncd16676a2016-07-20 16:23:011290TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521292
1293 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351294 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1295 MockRead("hello"),
1296 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1297 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061298 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521299 };
[email protected]31a2bfe2010-02-09 08:03:391300 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071301 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521302
[email protected]0b0bf032010-09-21 18:08:501303 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521304 "hello", "world"
1305 };
1306
1307 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421308 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521309 request.method = "GET";
bncce36dca22015-04-21 22:11:231310 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521311
bnc691fda62016-08-12 00:43:161312 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271313
[email protected]49639fa2011-12-20 23:22:411314 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521315
tfarina42834112016-09-22 13:38:201316 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521318
1319 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011320 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521321
bnc691fda62016-08-12 00:43:161322 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521323 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521324
wezca1070932016-05-26 20:30:521325 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251326 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471327 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521328
1329 std::string response_data;
bnc691fda62016-08-12 00:43:161330 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011331 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251332 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521333 }
1334}
1335
bncd16676a2016-07-20 16:23:011336TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091337 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221338 element_readers.push_back(
ricea2deef682016-09-09 08:04:071339 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221340 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271341
[email protected]1c773ea12009-04-28 19:58:421342 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521343 request.method = "POST";
1344 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271345 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521346
shivanishab9a143952016-09-19 17:23:411347 // Check the upload progress returned before initialization is correct.
1348 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1349 EXPECT_EQ(0u, progress.size());
1350 EXPECT_EQ(0u, progress.position());
1351
danakj1fd259a02016-04-16 03:17:091352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271354
initial.commit586acc5fe2008-07-26 22:42:521355 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351356 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1357 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1358 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061359 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521360 };
[email protected]31a2bfe2010-02-09 08:03:391361 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071362 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521363
[email protected]49639fa2011-12-20 23:22:411364 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521365
tfarina42834112016-09-22 13:38:201366 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521368
1369 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011370 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521371
bnc691fda62016-08-12 00:43:161372 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521373 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521374
wezca1070932016-05-26 20:30:521375 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251376 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521377
1378 std::string response_data;
bnc691fda62016-08-12 00:43:161379 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011380 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251381 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521382}
1383
[email protected]3a2d3662009-03-27 03:49:141384// This test is almost the same as Ignores100 above, but the response contains
1385// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571386// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011387TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421388 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141389 request.method = "GET";
1390 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141391
danakj1fd259a02016-04-16 03:17:091392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271394
[email protected]3a2d3662009-03-27 03:49:141395 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571396 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1397 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141398 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061399 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141400 };
[email protected]31a2bfe2010-02-09 08:03:391401 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071402 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141403
[email protected]49639fa2011-12-20 23:22:411404 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141405
tfarina42834112016-09-22 13:38:201406 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141408
1409 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011410 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141411
bnc691fda62016-08-12 00:43:161412 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521413 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141414
wezca1070932016-05-26 20:30:521415 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141416 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1417
1418 std::string response_data;
bnc691fda62016-08-12 00:43:161419 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011420 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141421 EXPECT_EQ("hello world", response_data);
1422}
1423
bncd16676a2016-07-20 16:23:011424TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081425 HttpRequestInfo request;
1426 request.method = "POST";
1427 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081428
danakj1fd259a02016-04-16 03:17:091429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161430 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081431
1432 MockRead data_reads[] = {
1433 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1434 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381435 };
zmo9528c9f42015-08-04 22:12:081436 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1437 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381438
zmo9528c9f42015-08-04 22:12:081439 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381440
tfarina42834112016-09-22 13:38:201441 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011442 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381443
zmo9528c9f42015-08-04 22:12:081444 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011445 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381446
zmo9528c9f42015-08-04 22:12:081447 std::string response_data;
bnc691fda62016-08-12 00:43:161448 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011449 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081450 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381451}
1452
bncd16676a2016-07-20 16:23:011453TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381454 HttpRequestInfo request;
1455 request.method = "POST";
1456 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381457
danakj1fd259a02016-04-16 03:17:091458 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161459 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271460
[email protected]ee9410e72010-01-07 01:42:381461 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061462 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381463 };
[email protected]31a2bfe2010-02-09 08:03:391464 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071465 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381466
[email protected]49639fa2011-12-20 23:22:411467 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381468
tfarina42834112016-09-22 13:38:201469 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381471
1472 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011473 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381474}
1475
[email protected]23e482282013-06-14 16:08:021476void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511477 const MockWrite* write_failure,
1478 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421479 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521480 request.method = "GET";
1481 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521482
vishal.b62985ca92015-04-17 08:45:511483 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071484 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271486
[email protected]202965992011-12-07 23:04:511487 // Written data for successfully sending both requests.
1488 MockWrite data1_writes[] = {
1489 MockWrite("GET / HTTP/1.1\r\n"
1490 "Host: www.foo.com\r\n"
1491 "Connection: keep-alive\r\n\r\n"),
1492 MockWrite("GET / HTTP/1.1\r\n"
1493 "Host: www.foo.com\r\n"
1494 "Connection: keep-alive\r\n\r\n")
1495 };
1496
1497 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521498 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351499 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1500 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061501 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521502 };
[email protected]202965992011-12-07 23:04:511503
1504 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491505 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511506 data1_writes[1] = *write_failure;
1507 } else {
1508 ASSERT_TRUE(read_failure);
1509 data1_reads[2] = *read_failure;
1510 }
1511
1512 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1513 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071514 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521515
1516 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351517 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1518 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061519 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521520 };
[email protected]31a2bfe2010-02-09 08:03:391521 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071522 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521523
thestig9d3bb0c2015-01-24 00:49:511524 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521525 "hello", "world"
1526 };
1527
mikecironef22f9812016-10-04 03:40:191528 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521529 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411530 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521531
bnc691fda62016-08-12 00:43:161532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521533
tfarina42834112016-09-22 13:38:201534 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011535 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521536
1537 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011538 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521539
[email protected]58e32bb2013-01-21 18:23:251540 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161541 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251542 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1543 if (i == 0) {
1544 first_socket_log_id = load_timing_info.socket_log_id;
1545 } else {
1546 // The second request should be using a new socket.
1547 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1548 }
1549
bnc691fda62016-08-12 00:43:161550 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521551 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521552
wezca1070932016-05-26 20:30:521553 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471554 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251555 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521556
1557 std::string response_data;
bnc691fda62016-08-12 00:43:161558 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011559 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251560 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521561 }
1562}
[email protected]3d2a59b2008-09-26 19:44:251563
[email protected]a34f61ee2014-03-18 20:59:491564void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1565 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101566 const MockRead* read_failure,
1567 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491568 HttpRequestInfo request;
1569 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101570 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491571
vishal.b62985ca92015-04-17 08:45:511572 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491573 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491575
[email protected]09356c652014-03-25 15:36:101576 SSLSocketDataProvider ssl1(ASYNC, OK);
1577 SSLSocketDataProvider ssl2(ASYNC, OK);
1578 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361579 ssl1.next_proto = kProtoHTTP2;
1580 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101581 }
1582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491584
[email protected]09356c652014-03-25 15:36:101585 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411586 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491587 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411588 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151589 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411590 SpdySerializedFrame spdy_data(
1591 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491592
[email protected]09356c652014-03-25 15:36:101593 // HTTP/1.1 versions of the request and response.
1594 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1595 "Host: www.foo.com\r\n"
1596 "Connection: keep-alive\r\n\r\n";
1597 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1598 const char kHttpData[] = "hello";
1599
1600 std::vector<MockRead> data1_reads;
1601 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491602 if (write_failure) {
1603 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101604 data1_writes.push_back(*write_failure);
1605 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491606 } else {
1607 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101608 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411609 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101610 } else {
1611 data1_writes.push_back(MockWrite(kHttpRequest));
1612 }
1613 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491614 }
1615
[email protected]09356c652014-03-25 15:36:101616 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1617 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491618 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1619
[email protected]09356c652014-03-25 15:36:101620 std::vector<MockRead> data2_reads;
1621 std::vector<MockWrite> data2_writes;
1622
1623 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411624 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101625
bncdf80d44fd2016-07-15 20:27:411626 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1627 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101628 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1629 } else {
1630 data2_writes.push_back(
1631 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1632
1633 data2_reads.push_back(
1634 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1635 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1636 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1637 }
rch8e6c6c42015-05-01 14:05:131638 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1639 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491640 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1641
1642 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591643 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491644 // Wait for the preconnect to complete.
1645 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1646 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101647 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491648
1649 // Make the request.
1650 TestCompletionCallback callback;
1651
bnc691fda62016-08-12 00:43:161652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491653
tfarina42834112016-09-22 13:38:201654 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491656
1657 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011658 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491659
1660 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161661 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101662 TestLoadTimingNotReused(
1663 load_timing_info,
1664 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491665
bnc691fda62016-08-12 00:43:161666 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521667 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491668
wezca1070932016-05-26 20:30:521669 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021670 if (response->was_fetched_via_spdy) {
1671 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1672 } else {
1673 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1674 }
[email protected]a34f61ee2014-03-18 20:59:491675
1676 std::string response_data;
bnc691fda62016-08-12 00:43:161677 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011678 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101679 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491680}
1681
bncd16676a2016-07-20 16:23:011682TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061683 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511684 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1685}
1686
bncd16676a2016-07-20 16:23:011687TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061688 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511689 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251690}
1691
bncd16676a2016-07-20 16:23:011692TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061693 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511694 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251695}
1696
[email protected]d58ceea82014-06-04 10:55:541697// Make sure that on a 408 response (Request Timeout), the request is retried,
1698// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011699TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541700 MockRead read_failure(SYNCHRONOUS,
1701 "HTTP/1.1 408 Request Timeout\r\n"
1702 "Connection: Keep-Alive\r\n"
1703 "Content-Length: 6\r\n\r\n"
1704 "Pickle");
1705 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1706}
1707
bncd16676a2016-07-20 16:23:011708TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491709 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101710 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491711}
1712
bncd16676a2016-07-20 16:23:011713TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491714 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101715 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491716}
1717
bncd16676a2016-07-20 16:23:011718TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491719 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101720 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1721}
1722
bncd16676a2016-07-20 16:23:011723TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101724 MockRead read_failure(ASYNC, OK); // EOF
1725 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1726}
1727
[email protected]d58ceea82014-06-04 10:55:541728// Make sure that on a 408 response (Request Timeout), the request is retried,
1729// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011730TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541731 MockRead read_failure(SYNCHRONOUS,
1732 "HTTP/1.1 408 Request Timeout\r\n"
1733 "Connection: Keep-Alive\r\n"
1734 "Content-Length: 6\r\n\r\n"
1735 "Pickle");
1736 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1737 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1738}
1739
bncd16676a2016-07-20 16:23:011740TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101741 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1742 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1743}
1744
bncd16676a2016-07-20 16:23:011745TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101746 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1747 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1748}
1749
bncd16676a2016-07-20 16:23:011750TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101751 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1752 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1753}
1754
bncd16676a2016-07-20 16:23:011755TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101756 MockRead read_failure(ASYNC, OK); // EOF
1757 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491758}
1759
bncd16676a2016-07-20 16:23:011760TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421761 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251762 request.method = "GET";
bncce36dca22015-04-21 22:11:231763 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251764
danakj1fd259a02016-04-16 03:17:091765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271767
[email protected]3d2a59b2008-09-26 19:44:251768 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061769 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351770 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1771 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061772 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251773 };
[email protected]31a2bfe2010-02-09 08:03:391774 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071775 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251776
[email protected]49639fa2011-12-20 23:22:411777 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251778
tfarina42834112016-09-22 13:38:201779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251781
1782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011783 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591784
1785 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161786 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591787 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251788}
1789
1790// What do various browsers do when the server closes a non-keepalive
1791// connection without sending any response header or body?
1792//
1793// IE7: error page
1794// Safari 3.1.2 (Windows): error page
1795// Firefox 3.0.1: blank page
1796// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421797// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1798// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011799TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251800 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061801 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351802 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1803 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061804 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251805 };
[email protected]31a2bfe2010-02-09 08:03:391806 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1807 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011808 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251809}
[email protected]1826a402014-01-08 15:40:481810
[email protected]7a5378b2012-11-04 03:25:171811// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1812// tests. There was a bug causing HttpNetworkTransaction to hang in the
1813// destructor in such situations.
1814// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011815TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171816 HttpRequestInfo request;
1817 request.method = "GET";
bncce36dca22015-04-21 22:11:231818 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171819
danakj1fd259a02016-04-16 03:17:091820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581821 auto trans =
1822 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171823
1824 MockRead data_reads[] = {
1825 MockRead("HTTP/1.0 200 OK\r\n"),
1826 MockRead("Connection: keep-alive\r\n"),
1827 MockRead("Content-Length: 100\r\n\r\n"),
1828 MockRead("hello"),
1829 MockRead(SYNCHRONOUS, 0),
1830 };
1831 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071832 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171833
1834 TestCompletionCallback callback;
1835
tfarina42834112016-09-22 13:38:201836 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171838
1839 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011840 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171841
1842 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501843 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171844 if (rv == ERR_IO_PENDING)
1845 rv = callback.WaitForResult();
1846 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501847 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011848 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171849
1850 trans.reset();
fdoray92e35a72016-06-10 15:54:551851 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171852 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1853}
1854
bncd16676a2016-07-20 16:23:011855TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171856 HttpRequestInfo request;
1857 request.method = "GET";
bncce36dca22015-04-21 22:11:231858 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171859
danakj1fd259a02016-04-16 03:17:091860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581861 auto trans =
1862 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171863
1864 MockRead data_reads[] = {
1865 MockRead("HTTP/1.0 200 OK\r\n"),
1866 MockRead("Connection: keep-alive\r\n"),
1867 MockRead("Content-Length: 100\r\n\r\n"),
1868 MockRead(SYNCHRONOUS, 0),
1869 };
1870 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171872
1873 TestCompletionCallback callback;
1874
tfarina42834112016-09-22 13:38:201875 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171877
1878 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011879 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171880
1881 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501882 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171883 if (rv == ERR_IO_PENDING)
1884 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011885 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171886
1887 trans.reset();
fdoray92e35a72016-06-10 15:54:551888 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171889 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1890}
1891
[email protected]0b0bf032010-09-21 18:08:501892// Test that we correctly reuse a keep-alive connection after not explicitly
1893// reading the body.
bncd16676a2016-07-20 16:23:011894TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131895 HttpRequestInfo request;
1896 request.method = "GET";
1897 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131898
vishal.b62985ca92015-04-17 08:45:511899 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071900 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091901 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271902
mmenkecc2298e2015-12-07 18:20:181903 const char* request_data =
1904 "GET / HTTP/1.1\r\n"
1905 "Host: www.foo.com\r\n"
1906 "Connection: keep-alive\r\n\r\n";
1907 MockWrite data_writes[] = {
1908 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1909 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1910 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1911 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1912 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1913 };
1914
[email protected]0b0bf032010-09-21 18:08:501915 // Note that because all these reads happen in the same
1916 // StaticSocketDataProvider, it shows that the same socket is being reused for
1917 // all transactions.
mmenkecc2298e2015-12-07 18:20:181918 MockRead data_reads[] = {
1919 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1920 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1921 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1922 MockRead(ASYNC, 7,
1923 "HTTP/1.1 302 Found\r\n"
1924 "Content-Length: 0\r\n\r\n"),
1925 MockRead(ASYNC, 9,
1926 "HTTP/1.1 302 Found\r\n"
1927 "Content-Length: 5\r\n\r\n"
1928 "hello"),
1929 MockRead(ASYNC, 11,
1930 "HTTP/1.1 301 Moved Permanently\r\n"
1931 "Content-Length: 0\r\n\r\n"),
1932 MockRead(ASYNC, 13,
1933 "HTTP/1.1 301 Moved Permanently\r\n"
1934 "Content-Length: 5\r\n\r\n"
1935 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131936
mmenkecc2298e2015-12-07 18:20:181937 // In the next two rounds, IsConnectedAndIdle returns false, due to
1938 // the set_busy_before_sync_reads(true) call, while the
1939 // HttpNetworkTransaction is being shut down, but the socket is still
1940 // reuseable. See http://crbug.com/544255.
1941 MockRead(ASYNC, 15,
1942 "HTTP/1.1 200 Hunky-Dory\r\n"
1943 "Content-Length: 5\r\n\r\n"),
1944 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131945
mmenkecc2298e2015-12-07 18:20:181946 MockRead(ASYNC, 18,
1947 "HTTP/1.1 200 Hunky-Dory\r\n"
1948 "Content-Length: 5\r\n\r\n"
1949 "he"),
1950 MockRead(SYNCHRONOUS, 19, "llo"),
1951
1952 // The body of the final request is actually read.
1953 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1954 MockRead(ASYNC, 22, "hello"),
1955 };
1956 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1957 arraysize(data_writes));
1958 data.set_busy_before_sync_reads(true);
1959 session_deps_.socket_factory->AddSocketDataProvider(&data);
1960
1961 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501962 std::string response_lines[kNumUnreadBodies];
1963
mikecironef22f9812016-10-04 03:40:191964 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181965 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411966 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131967
bnc87dcefc2017-05-25 12:47:581968 auto trans = base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
1969 session.get());
[email protected]fc31d6a42010-06-24 18:05:131970
tfarina42834112016-09-22 13:38:201971 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011972 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131973
[email protected]58e32bb2013-01-21 18:23:251974 LoadTimingInfo load_timing_info;
1975 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1976 if (i == 0) {
1977 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1978 first_socket_log_id = load_timing_info.socket_log_id;
1979 } else {
1980 TestLoadTimingReused(load_timing_info);
1981 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1982 }
1983
[email protected]fc31d6a42010-06-24 18:05:131984 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181985 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131986
mmenkecc2298e2015-12-07 18:20:181987 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501988 response_lines[i] = response->headers->GetStatusLine();
1989
mmenkecc2298e2015-12-07 18:20:181990 // Delete the transaction without reading the response bodies. Then spin
1991 // the message loop, so the response bodies are drained.
1992 trans.reset();
1993 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131994 }
[email protected]0b0bf032010-09-21 18:08:501995
1996 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181997 "HTTP/1.1 204 No Content",
1998 "HTTP/1.1 205 Reset Content",
1999 "HTTP/1.1 304 Not Modified",
2000 "HTTP/1.1 302 Found",
2001 "HTTP/1.1 302 Found",
2002 "HTTP/1.1 301 Moved Permanently",
2003 "HTTP/1.1 301 Moved Permanently",
2004 "HTTP/1.1 200 Hunky-Dory",
2005 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502006 };
2007
mostynb91e0da982015-01-20 19:17:272008 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2009 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502010
2011 for (int i = 0; i < kNumUnreadBodies; ++i)
2012 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2013
[email protected]49639fa2011-12-20 23:22:412014 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202016 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012017 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162018 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182019 ASSERT_TRUE(response);
2020 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502021 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2022 std::string response_data;
bnc691fda62016-08-12 00:43:162023 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012024 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502025 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132026}
2027
mmenke5f94fda2016-06-02 20:54:132028// Sockets that receive extra data after a response is complete should not be
2029// reused.
bncd16676a2016-07-20 16:23:012030TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2032 MockWrite data_writes1[] = {
2033 MockWrite("HEAD / HTTP/1.1\r\n"
2034 "Host: www.borked.com\r\n"
2035 "Connection: keep-alive\r\n\r\n"),
2036 };
2037
2038 MockRead data_reads1[] = {
2039 MockRead("HTTP/1.1 200 OK\r\n"
2040 "Connection: keep-alive\r\n"
2041 "Content-Length: 22\r\n\r\n"
2042 "This server is borked."),
2043 };
2044
2045 MockWrite data_writes2[] = {
2046 MockWrite("GET /foo HTTP/1.1\r\n"
2047 "Host: www.borked.com\r\n"
2048 "Connection: keep-alive\r\n\r\n"),
2049 };
2050
2051 MockRead data_reads2[] = {
2052 MockRead("HTTP/1.1 200 OK\r\n"
2053 "Content-Length: 3\r\n\r\n"
2054 "foo"),
2055 };
2056 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2057 data_writes1, arraysize(data_writes1));
2058 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2059 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2060 data_writes2, arraysize(data_writes2));
2061 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2062
2063 TestCompletionCallback callback;
2064 HttpRequestInfo request1;
2065 request1.method = "HEAD";
2066 request1.url = GURL("http://www.borked.com/");
2067
bnc87dcefc2017-05-25 12:47:582068 auto trans1 =
2069 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202070 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012071 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132072
2073 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2074 ASSERT_TRUE(response1);
2075 ASSERT_TRUE(response1->headers);
2076 EXPECT_EQ(200, response1->headers->response_code());
2077 EXPECT_TRUE(response1->headers->IsKeepAlive());
2078
2079 std::string response_data1;
robpercival214763f2016-07-01 23:27:012080 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132081 EXPECT_EQ("", response_data1);
2082 // Deleting the transaction attempts to release the socket back into the
2083 // socket pool.
2084 trans1.reset();
2085
2086 HttpRequestInfo request2;
2087 request2.method = "GET";
2088 request2.url = GURL("http://www.borked.com/foo");
2089
bnc87dcefc2017-05-25 12:47:582090 auto trans2 =
2091 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202092 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012093 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132094
2095 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2096 ASSERT_TRUE(response2);
2097 ASSERT_TRUE(response2->headers);
2098 EXPECT_EQ(200, response2->headers->response_code());
2099
2100 std::string response_data2;
robpercival214763f2016-07-01 23:27:012101 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132102 EXPECT_EQ("foo", response_data2);
2103}
2104
bncd16676a2016-07-20 16:23:012105TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2107 MockWrite data_writes1[] = {
2108 MockWrite("GET / HTTP/1.1\r\n"
2109 "Host: www.borked.com\r\n"
2110 "Connection: keep-alive\r\n\r\n"),
2111 };
2112
2113 MockRead data_reads1[] = {
2114 MockRead("HTTP/1.1 200 OK\r\n"
2115 "Connection: keep-alive\r\n"
2116 "Content-Length: 22\r\n\r\n"
2117 "This server is borked."
2118 "Bonus data!"),
2119 };
2120
2121 MockWrite data_writes2[] = {
2122 MockWrite("GET /foo HTTP/1.1\r\n"
2123 "Host: www.borked.com\r\n"
2124 "Connection: keep-alive\r\n\r\n"),
2125 };
2126
2127 MockRead data_reads2[] = {
2128 MockRead("HTTP/1.1 200 OK\r\n"
2129 "Content-Length: 3\r\n\r\n"
2130 "foo"),
2131 };
2132 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2133 data_writes1, arraysize(data_writes1));
2134 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2135 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2136 data_writes2, arraysize(data_writes2));
2137 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2138
2139 TestCompletionCallback callback;
2140 HttpRequestInfo request1;
2141 request1.method = "GET";
2142 request1.url = GURL("http://www.borked.com/");
2143
bnc87dcefc2017-05-25 12:47:582144 auto trans1 =
2145 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202146 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012147 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132148
2149 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2150 ASSERT_TRUE(response1);
2151 ASSERT_TRUE(response1->headers);
2152 EXPECT_EQ(200, response1->headers->response_code());
2153 EXPECT_TRUE(response1->headers->IsKeepAlive());
2154
2155 std::string response_data1;
robpercival214763f2016-07-01 23:27:012156 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132157 EXPECT_EQ("This server is borked.", response_data1);
2158 // Deleting the transaction attempts to release the socket back into the
2159 // socket pool.
2160 trans1.reset();
2161
2162 HttpRequestInfo request2;
2163 request2.method = "GET";
2164 request2.url = GURL("http://www.borked.com/foo");
2165
bnc87dcefc2017-05-25 12:47:582166 auto trans2 =
2167 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202168 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012169 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132170
2171 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2172 ASSERT_TRUE(response2);
2173 ASSERT_TRUE(response2->headers);
2174 EXPECT_EQ(200, response2->headers->response_code());
2175
2176 std::string response_data2;
robpercival214763f2016-07-01 23:27:012177 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132178 EXPECT_EQ("foo", response_data2);
2179}
2180
bncd16676a2016-07-20 16:23:012181TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132182 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2183 MockWrite data_writes1[] = {
2184 MockWrite("GET / HTTP/1.1\r\n"
2185 "Host: www.borked.com\r\n"
2186 "Connection: keep-alive\r\n\r\n"),
2187 };
2188
2189 MockRead data_reads1[] = {
2190 MockRead("HTTP/1.1 200 OK\r\n"
2191 "Connection: keep-alive\r\n"
2192 "Transfer-Encoding: chunked\r\n\r\n"),
2193 MockRead("16\r\nThis server is borked.\r\n"),
2194 MockRead("0\r\n\r\nBonus data!"),
2195 };
2196
2197 MockWrite data_writes2[] = {
2198 MockWrite("GET /foo HTTP/1.1\r\n"
2199 "Host: www.borked.com\r\n"
2200 "Connection: keep-alive\r\n\r\n"),
2201 };
2202
2203 MockRead data_reads2[] = {
2204 MockRead("HTTP/1.1 200 OK\r\n"
2205 "Content-Length: 3\r\n\r\n"
2206 "foo"),
2207 };
2208 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2209 data_writes1, arraysize(data_writes1));
2210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2211 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2212 data_writes2, arraysize(data_writes2));
2213 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2214
2215 TestCompletionCallback callback;
2216 HttpRequestInfo request1;
2217 request1.method = "GET";
2218 request1.url = GURL("http://www.borked.com/");
2219
bnc87dcefc2017-05-25 12:47:582220 auto trans1 =
2221 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202222 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012223 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132224
2225 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2226 ASSERT_TRUE(response1);
2227 ASSERT_TRUE(response1->headers);
2228 EXPECT_EQ(200, response1->headers->response_code());
2229 EXPECT_TRUE(response1->headers->IsKeepAlive());
2230
2231 std::string response_data1;
robpercival214763f2016-07-01 23:27:012232 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132233 EXPECT_EQ("This server is borked.", response_data1);
2234 // Deleting the transaction attempts to release the socket back into the
2235 // socket pool.
2236 trans1.reset();
2237
2238 HttpRequestInfo request2;
2239 request2.method = "GET";
2240 request2.url = GURL("http://www.borked.com/foo");
2241
bnc87dcefc2017-05-25 12:47:582242 auto trans2 =
2243 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202244 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012245 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132246
2247 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2248 ASSERT_TRUE(response2);
2249 ASSERT_TRUE(response2->headers);
2250 EXPECT_EQ(200, response2->headers->response_code());
2251
2252 std::string response_data2;
robpercival214763f2016-07-01 23:27:012253 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132254 EXPECT_EQ("foo", response_data2);
2255}
2256
2257// This is a little different from the others - it tests the case that the
2258// HttpStreamParser doesn't know if there's extra data on a socket or not when
2259// the HttpNetworkTransaction is torn down, because the response body hasn't
2260// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012261TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2263 MockWrite data_writes1[] = {
2264 MockWrite("GET / HTTP/1.1\r\n"
2265 "Host: www.borked.com\r\n"
2266 "Connection: keep-alive\r\n\r\n"),
2267 };
2268
2269 MockRead data_reads1[] = {
2270 MockRead("HTTP/1.1 200 OK\r\n"
2271 "Connection: keep-alive\r\n"
2272 "Transfer-Encoding: chunked\r\n\r\n"),
2273 MockRead("16\r\nThis server is borked.\r\n"),
2274 MockRead("0\r\n\r\nBonus data!"),
2275 };
2276 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2277 data_writes1, arraysize(data_writes1));
2278 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2279
2280 TestCompletionCallback callback;
2281 HttpRequestInfo request1;
2282 request1.method = "GET";
2283 request1.url = GURL("http://www.borked.com/");
2284
bnc87dcefc2017-05-25 12:47:582285 auto trans =
2286 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2287 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012288 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132289
bnc87dcefc2017-05-25 12:47:582290 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132291 ASSERT_TRUE(response1);
2292 ASSERT_TRUE(response1->headers);
2293 EXPECT_EQ(200, response1->headers->response_code());
2294 EXPECT_TRUE(response1->headers->IsKeepAlive());
2295
2296 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2297 // response body.
bnc87dcefc2017-05-25 12:47:582298 trans.reset();
mmenke5f94fda2016-06-02 20:54:132299
2300 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2301 // socket can't be reused, rather than returning it to the socket pool.
2302 base::RunLoop().RunUntilIdle();
2303
2304 // There should be no idle sockets in the pool.
2305 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2306}
2307
[email protected]038e9a32008-10-08 22:40:162308// Test the request-challenge-retry sequence for basic auth.
2309// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012310TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422311 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162312 request.method = "GET";
bncce36dca22015-04-21 22:11:232313 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162314
vishal.b62985ca92015-04-17 08:45:512315 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072316 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162318 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272319
[email protected]f9ee6b52008-11-08 06:46:232320 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232321 MockWrite(
2322 "GET / HTTP/1.1\r\n"
2323 "Host: www.example.org\r\n"
2324 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232325 };
2326
[email protected]038e9a32008-10-08 22:40:162327 MockRead data_reads1[] = {
2328 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2329 // Give a couple authenticate options (only the middle one is actually
2330 // supported).
[email protected]22927ad2009-09-21 19:56:192331 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162332 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2333 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2334 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2335 // Large content-length -- won't matter, as connection will be reset.
2336 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062337 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162338 };
2339
2340 // After calling trans->RestartWithAuth(), this is the request we should
2341 // be issuing -- the final header line contains the credentials.
2342 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232343 MockWrite(
2344 "GET / HTTP/1.1\r\n"
2345 "Host: www.example.org\r\n"
2346 "Connection: keep-alive\r\n"
2347 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162348 };
2349
2350 // Lastly, the server responds with the actual content.
2351 MockRead data_reads2[] = {
2352 MockRead("HTTP/1.0 200 OK\r\n"),
2353 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2354 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062355 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162356 };
2357
[email protected]31a2bfe2010-02-09 08:03:392358 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2359 data_writes1, arraysize(data_writes1));
2360 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2361 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072362 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2363 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162364
[email protected]49639fa2011-12-20 23:22:412365 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162366
tfarina42834112016-09-22 13:38:202367 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162369
2370 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012371 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162372
[email protected]58e32bb2013-01-21 18:23:252373 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162374 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252375 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2376
sclittlefb249892015-09-10 21:33:222377 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162378 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222379 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162380 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192381
bnc691fda62016-08-12 00:43:162382 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522383 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042384 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162385
[email protected]49639fa2011-12-20 23:22:412386 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162387
bnc691fda62016-08-12 00:43:162388 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162390
2391 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012392 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162393
[email protected]58e32bb2013-01-21 18:23:252394 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162395 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252396 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2397 // The load timing after restart should have a new socket ID, and times after
2398 // those of the first load timing.
2399 EXPECT_LE(load_timing_info1.receive_headers_end,
2400 load_timing_info2.connect_timing.connect_start);
2401 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2402
sclittlefb249892015-09-10 21:33:222403 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162404 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222405 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162406 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192407
bnc691fda62016-08-12 00:43:162408 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522409 ASSERT_TRUE(response);
2410 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162411 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162412}
2413
ttuttled9dbc652015-09-29 20:00:592414// Test the request-challenge-retry sequence for basic auth.
2415// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012416TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592417 HttpRequestInfo request;
2418 request.method = "GET";
2419 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592420
2421 TestNetLog log;
2422 MockHostResolver* resolver = new MockHostResolver();
2423 session_deps_.net_log = &log;
2424 session_deps_.host_resolver.reset(resolver);
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());
ttuttled9dbc652015-09-29 20:00:592427
2428 resolver->rules()->ClearRules();
2429 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2430
2431 MockWrite data_writes1[] = {
2432 MockWrite("GET / HTTP/1.1\r\n"
2433 "Host: www.example.org\r\n"
2434 "Connection: keep-alive\r\n\r\n"),
2435 };
2436
2437 MockRead data_reads1[] = {
2438 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2439 // Give a couple authenticate options (only the middle one is actually
2440 // supported).
2441 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2442 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2443 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2444 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2445 // Large content-length -- won't matter, as connection will be reset.
2446 MockRead("Content-Length: 10000\r\n\r\n"),
2447 MockRead(SYNCHRONOUS, ERR_FAILED),
2448 };
2449
2450 // After calling trans->RestartWithAuth(), this is the request we should
2451 // be issuing -- the final header line contains the credentials.
2452 MockWrite data_writes2[] = {
2453 MockWrite("GET / HTTP/1.1\r\n"
2454 "Host: www.example.org\r\n"
2455 "Connection: keep-alive\r\n"
2456 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2457 };
2458
2459 // Lastly, the server responds with the actual content.
2460 MockRead data_reads2[] = {
2461 MockRead("HTTP/1.0 200 OK\r\n"),
2462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2463 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2464 };
2465
2466 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));
2470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2471 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2472
2473 TestCompletionCallback callback1;
2474
bnc691fda62016-08-12 00:43:162475 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202476 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592477
2478 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162479 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592480 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2481
2482 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162483 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592484 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162485 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592486
bnc691fda62016-08-12 00:43:162487 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592488 ASSERT_TRUE(response);
2489 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2490
2491 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162492 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592493 ASSERT_FALSE(endpoint.address().empty());
2494 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2495
2496 resolver->rules()->ClearRules();
2497 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2498
2499 TestCompletionCallback callback2;
2500
bnc691fda62016-08-12 00:43:162501 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592502 AuthCredentials(kFoo, kBar), callback2.callback())));
2503
2504 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162505 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592506 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2507 // The load timing after restart should have a new socket ID, and times after
2508 // those of the first load timing.
2509 EXPECT_LE(load_timing_info1.receive_headers_end,
2510 load_timing_info2.connect_timing.connect_start);
2511 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2512
2513 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162514 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592515 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162516 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592517
bnc691fda62016-08-12 00:43:162518 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592519 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522520 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592521 EXPECT_EQ(100, response->headers->GetContentLength());
2522
bnc691fda62016-08-12 00:43:162523 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592524 ASSERT_FALSE(endpoint.address().empty());
2525 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2526}
2527
bncd16676a2016-07-20 16:23:012528TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462529 HttpRequestInfo request;
2530 request.method = "GET";
bncce36dca22015-04-21 22:11:232531 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292532 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462533
danakj1fd259a02016-04-16 03:17:092534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162535 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272536
[email protected]861fcd52009-08-26 02:33:462537 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232538 MockWrite(
2539 "GET / HTTP/1.1\r\n"
2540 "Host: www.example.org\r\n"
2541 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462542 };
2543
2544 MockRead data_reads[] = {
2545 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2546 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2548 // Large content-length -- won't matter, as connection will be reset.
2549 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062550 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462551 };
2552
[email protected]31a2bfe2010-02-09 08:03:392553 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2554 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072555 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412556 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462557
tfarina42834112016-09-22 13:38:202558 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462560
2561 rv = callback.WaitForResult();
2562 EXPECT_EQ(0, rv);
2563
sclittlefb249892015-09-10 21:33:222564 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162565 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222566 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162567 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192568
bnc691fda62016-08-12 00:43:162569 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522570 ASSERT_TRUE(response);
2571 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462572}
2573
[email protected]2d2697f92009-02-18 21:00:322574// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2575// connection.
bncd16676a2016-07-20 16:23:012576TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182577 // On the second pass, the body read of the auth challenge is synchronous, so
2578 // IsConnectedAndIdle returns false. The socket should still be drained and
2579 // reused. See http://crbug.com/544255.
2580 for (int i = 0; i < 2; ++i) {
2581 HttpRequestInfo request;
2582 request.method = "GET";
2583 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322584
mmenkecc2298e2015-12-07 18:20:182585 TestNetLog log;
2586 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272588
mmenkecc2298e2015-12-07 18:20:182589 MockWrite data_writes[] = {
2590 MockWrite(ASYNC, 0,
2591 "GET / HTTP/1.1\r\n"
2592 "Host: www.example.org\r\n"
2593 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322594
bnc691fda62016-08-12 00:43:162595 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182596 // be issuing -- the final header line contains the credentials.
2597 MockWrite(ASYNC, 6,
2598 "GET / HTTP/1.1\r\n"
2599 "Host: www.example.org\r\n"
2600 "Connection: keep-alive\r\n"
2601 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2602 };
[email protected]2d2697f92009-02-18 21:00:322603
mmenkecc2298e2015-12-07 18:20:182604 MockRead data_reads[] = {
2605 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2606 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2607 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2608 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2609 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322610
mmenkecc2298e2015-12-07 18:20:182611 // Lastly, the server responds with the actual content.
2612 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2613 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2614 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2615 MockRead(ASYNC, 10, "Hello"),
2616 };
[email protected]2d2697f92009-02-18 21:00:322617
mmenkecc2298e2015-12-07 18:20:182618 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2619 arraysize(data_writes));
2620 data.set_busy_before_sync_reads(true);
2621 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462622
mmenkecc2298e2015-12-07 18:20:182623 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322624
bnc691fda62016-08-12 00:43:162625 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202626 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012627 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322628
mmenkecc2298e2015-12-07 18:20:182629 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162630 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182631 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322632
bnc691fda62016-08-12 00:43:162633 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182634 ASSERT_TRUE(response);
2635 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322636
mmenkecc2298e2015-12-07 18:20:182637 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252638
bnc691fda62016-08-12 00:43:162639 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2640 callback2.callback());
robpercival214763f2016-07-01 23:27:012641 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322642
mmenkecc2298e2015-12-07 18:20:182643 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162644 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182645 TestLoadTimingReused(load_timing_info2);
2646 // The load timing after restart should have the same socket ID, and times
2647 // those of the first load timing.
2648 EXPECT_LE(load_timing_info1.receive_headers_end,
2649 load_timing_info2.send_start);
2650 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322651
bnc691fda62016-08-12 00:43:162652 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182653 ASSERT_TRUE(response);
2654 EXPECT_FALSE(response->auth_challenge);
2655 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322656
mmenkecc2298e2015-12-07 18:20:182657 std::string response_data;
bnc691fda62016-08-12 00:43:162658 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322659
mmenkecc2298e2015-12-07 18:20:182660 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162661 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182662 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162663 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182664 }
[email protected]2d2697f92009-02-18 21:00:322665}
2666
2667// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2668// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012669TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422670 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322671 request.method = "GET";
bncce36dca22015-04-21 22:11:232672 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322673
danakj1fd259a02016-04-16 03:17:092674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272675
[email protected]2d2697f92009-02-18 21:00:322676 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162677 MockWrite("GET / HTTP/1.1\r\n"
2678 "Host: www.example.org\r\n"
2679 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322680
bnc691fda62016-08-12 00:43:162681 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232682 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162683 MockWrite("GET / HTTP/1.1\r\n"
2684 "Host: www.example.org\r\n"
2685 "Connection: keep-alive\r\n"
2686 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322687 };
2688
[email protected]2d2697f92009-02-18 21:00:322689 MockRead data_reads1[] = {
2690 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2691 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312692 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322693
2694 // Lastly, the server responds with the actual content.
2695 MockRead("HTTP/1.1 200 OK\r\n"),
2696 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502697 MockRead("Content-Length: 5\r\n\r\n"),
2698 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322699 };
2700
[email protected]2d0a4f92011-05-05 16:38:462701 // An incorrect reconnect would cause this to be read.
2702 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062703 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462704 };
2705
[email protected]31a2bfe2010-02-09 08:03:392706 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2707 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462708 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2709 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072710 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2711 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322712
[email protected]49639fa2011-12-20 23:22:412713 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322714
bnc691fda62016-08-12 00:43:162715 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202716 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322718
2719 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012720 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322721
bnc691fda62016-08-12 00:43:162722 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522723 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042724 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322725
[email protected]49639fa2011-12-20 23:22:412726 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322727
bnc691fda62016-08-12 00:43:162728 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322730
2731 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012732 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322733
bnc691fda62016-08-12 00:43:162734 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522735 ASSERT_TRUE(response);
2736 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502737 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322738}
2739
2740// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2741// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012742TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422743 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322744 request.method = "GET";
bncce36dca22015-04-21 22:11:232745 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322746
danakj1fd259a02016-04-16 03:17:092747 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272748
[email protected]2d2697f92009-02-18 21:00:322749 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162750 MockWrite("GET / HTTP/1.1\r\n"
2751 "Host: www.example.org\r\n"
2752 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322753
bnc691fda62016-08-12 00:43:162754 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232755 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162756 MockWrite("GET / HTTP/1.1\r\n"
2757 "Host: www.example.org\r\n"
2758 "Connection: keep-alive\r\n"
2759 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322760 };
2761
2762 // Respond with 5 kb of response body.
2763 std::string large_body_string("Unauthorized");
2764 large_body_string.append(5 * 1024, ' ');
2765 large_body_string.append("\r\n");
2766
2767 MockRead data_reads1[] = {
2768 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2769 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2770 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2771 // 5134 = 12 + 5 * 1024 + 2
2772 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062773 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322774
2775 // Lastly, the server responds with the actual content.
2776 MockRead("HTTP/1.1 200 OK\r\n"),
2777 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502778 MockRead("Content-Length: 5\r\n\r\n"),
2779 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322780 };
2781
[email protected]2d0a4f92011-05-05 16:38:462782 // An incorrect reconnect would cause this to be read.
2783 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062784 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462785 };
2786
[email protected]31a2bfe2010-02-09 08:03:392787 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2788 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462789 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2790 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2792 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322793
[email protected]49639fa2011-12-20 23:22:412794 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322795
bnc691fda62016-08-12 00:43:162796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202797 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322799
2800 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012801 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322802
bnc691fda62016-08-12 00:43:162803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522804 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042805 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322806
[email protected]49639fa2011-12-20 23:22:412807 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322808
bnc691fda62016-08-12 00:43:162809 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322811
2812 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012813 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322814
bnc691fda62016-08-12 00:43:162815 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522816 ASSERT_TRUE(response);
2817 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502818 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322819}
2820
2821// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312822// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012823TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312824 HttpRequestInfo request;
2825 request.method = "GET";
bncce36dca22015-04-21 22:11:232826 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312827
danakj1fd259a02016-04-16 03:17:092828 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272829
[email protected]11203f012009-11-12 23:02:312830 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232831 MockWrite(
2832 "GET / HTTP/1.1\r\n"
2833 "Host: www.example.org\r\n"
2834 "Connection: keep-alive\r\n\r\n"),
2835 // This simulates the seemingly successful write to a closed connection
2836 // if the bug is not fixed.
2837 MockWrite(
2838 "GET / HTTP/1.1\r\n"
2839 "Host: www.example.org\r\n"
2840 "Connection: keep-alive\r\n"
2841 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312842 };
2843
2844 MockRead data_reads1[] = {
2845 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2846 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2847 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2848 MockRead("Content-Length: 14\r\n\r\n"),
2849 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062850 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312851 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062852 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312853 };
2854
bnc691fda62016-08-12 00:43:162855 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312856 // be issuing -- the final header line contains the credentials.
2857 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232858 MockWrite(
2859 "GET / HTTP/1.1\r\n"
2860 "Host: www.example.org\r\n"
2861 "Connection: keep-alive\r\n"
2862 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312863 };
2864
2865 // Lastly, the server responds with the actual content.
2866 MockRead data_reads2[] = {
2867 MockRead("HTTP/1.1 200 OK\r\n"),
2868 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502869 MockRead("Content-Length: 5\r\n\r\n"),
2870 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312871 };
2872
[email protected]31a2bfe2010-02-09 08:03:392873 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2874 data_writes1, arraysize(data_writes1));
2875 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2876 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2878 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312879
[email protected]49639fa2011-12-20 23:22:412880 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312881
bnc691fda62016-08-12 00:43:162882 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202883 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312885
2886 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012887 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312888
bnc691fda62016-08-12 00:43:162889 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522890 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042891 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312892
[email protected]49639fa2011-12-20 23:22:412893 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312894
bnc691fda62016-08-12 00:43:162895 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312897
2898 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012899 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312900
bnc691fda62016-08-12 00:43:162901 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522902 ASSERT_TRUE(response);
2903 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502904 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312905}
2906
[email protected]394816e92010-08-03 07:38:592907// Test the request-challenge-retry sequence for basic auth, over a connection
2908// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012909TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012910 HttpRequestInfo request;
2911 request.method = "GET";
bncce36dca22015-04-21 22:11:232912 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012913 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292914 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012915
2916 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032917 session_deps_.proxy_service =
2918 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512919 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012920 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012922
2923 // Since we have proxy, should try to establish tunnel.
2924 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542925 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172926 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542927 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012928 };
2929
mmenkee71e15332015-10-07 16:39:542930 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012931 // connection.
2932 MockRead data_reads1[] = {
2933 // No credentials.
2934 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2935 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542936 };
ttuttle34f63b52015-03-05 04:33:012937
mmenkee71e15332015-10-07 16:39:542938 // Since the first connection couldn't be reused, need to establish another
2939 // once given credentials.
2940 MockWrite data_writes2[] = {
2941 // After calling trans->RestartWithAuth(), this is the request we should
2942 // be issuing -- the final header line contains the credentials.
2943 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172944 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542945 "Proxy-Connection: keep-alive\r\n"
2946 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2947
2948 MockWrite("GET / HTTP/1.1\r\n"
2949 "Host: www.example.org\r\n"
2950 "Connection: keep-alive\r\n\r\n"),
2951 };
2952
2953 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012954 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2955
2956 MockRead("HTTP/1.1 200 OK\r\n"),
2957 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2958 MockRead("Content-Length: 5\r\n\r\n"),
2959 MockRead(SYNCHRONOUS, "hello"),
2960 };
2961
2962 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2963 data_writes1, arraysize(data_writes1));
2964 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542965 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2966 data_writes2, arraysize(data_writes2));
2967 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012968 SSLSocketDataProvider ssl(ASYNC, OK);
2969 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2970
2971 TestCompletionCallback callback1;
2972
bnc87dcefc2017-05-25 12:47:582973 auto trans =
2974 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:012975
2976 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012978
2979 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012980 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462981 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012982 log.GetEntries(&entries);
2983 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002984 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2985 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012986 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002987 entries, pos,
2988 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2989 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012990
2991 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522992 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012993 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522994 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012995 EXPECT_EQ(407, response->headers->response_code());
2996 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2997 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2998
2999 LoadTimingInfo load_timing_info;
3000 // CONNECT requests and responses are handled at the connect job level, so
3001 // the transaction does not yet have a connection.
3002 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3003
3004 TestCompletionCallback callback2;
3005
3006 rv =
3007 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013009
3010 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013011 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013012
3013 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523014 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013015
3016 EXPECT_TRUE(response->headers->IsKeepAlive());
3017 EXPECT_EQ(200, response->headers->response_code());
3018 EXPECT_EQ(5, response->headers->GetContentLength());
3019 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3020
3021 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523022 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013023
3024 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3025 TestLoadTimingNotReusedWithPac(load_timing_info,
3026 CONNECT_TIMING_HAS_SSL_TIMES);
3027
3028 trans.reset();
3029 session->CloseAllConnections();
3030}
3031
3032// Test the request-challenge-retry sequence for basic auth, over a connection
3033// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013034TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593035 HttpRequestInfo request;
3036 request.method = "GET";
bncce36dca22015-04-21 22:11:233037 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593038 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293039 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593040
[email protected]cb9bf6ca2011-01-28 13:15:273041 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033042 session_deps_.proxy_service =
3043 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513044 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073045 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093046 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273047
[email protected]394816e92010-08-03 07:38:593048 // Since we have proxy, should try to establish tunnel.
3049 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543050 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173051 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543052 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113053 };
3054
mmenkee71e15332015-10-07 16:39:543055 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083056 // connection.
3057 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543058 // No credentials.
3059 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3060 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3061 MockRead("Proxy-Connection: close\r\n\r\n"),
3062 };
mmenkee0b5c882015-08-26 20:29:113063
mmenkee71e15332015-10-07 16:39:543064 MockWrite data_writes2[] = {
3065 // After calling trans->RestartWithAuth(), this is the request we should
3066 // be issuing -- the final header line contains the credentials.
3067 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173068 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543069 "Proxy-Connection: keep-alive\r\n"
3070 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083071
mmenkee71e15332015-10-07 16:39:543072 MockWrite("GET / HTTP/1.1\r\n"
3073 "Host: www.example.org\r\n"
3074 "Connection: keep-alive\r\n\r\n"),
3075 };
3076
3077 MockRead data_reads2[] = {
3078 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3079
3080 MockRead("HTTP/1.1 200 OK\r\n"),
3081 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3082 MockRead("Content-Length: 5\r\n\r\n"),
3083 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593084 };
3085
3086 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3087 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073088 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543089 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3090 data_writes2, arraysize(data_writes2));
3091 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063092 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593094
[email protected]49639fa2011-12-20 23:22:413095 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593096
bnc87dcefc2017-05-25 12:47:583097 auto trans =
3098 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503099
[email protected]49639fa2011-12-20 23:22:413100 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013101 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593102
3103 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013104 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463105 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403106 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593107 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003108 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3109 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593110 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403111 entries, pos,
mikecirone8b85c432016-09-08 19:11:003112 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3113 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593114
3115 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523116 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013117 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523118 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593119 EXPECT_EQ(407, response->headers->response_code());
3120 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043121 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593122
[email protected]029c83b62013-01-24 05:28:203123 LoadTimingInfo load_timing_info;
3124 // CONNECT requests and responses are handled at the connect job level, so
3125 // the transaction does not yet have a connection.
3126 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3127
[email protected]49639fa2011-12-20 23:22:413128 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593129
[email protected]49639fa2011-12-20 23:22:413130 rv = trans->RestartWithAuth(
3131 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593133
3134 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013135 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593136
3137 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523138 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593139
3140 EXPECT_TRUE(response->headers->IsKeepAlive());
3141 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503142 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593143 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3144
3145 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523146 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503147
[email protected]029c83b62013-01-24 05:28:203148 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3149 TestLoadTimingNotReusedWithPac(load_timing_info,
3150 CONNECT_TIMING_HAS_SSL_TIMES);
3151
[email protected]0b0bf032010-09-21 18:08:503152 trans.reset();
[email protected]102e27c2011-02-23 01:01:313153 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593154}
3155
[email protected]11203f012009-11-12 23:02:313156// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013157// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013158TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233159 // On the second pass, the body read of the auth challenge is synchronous, so
3160 // IsConnectedAndIdle returns false. The socket should still be drained and
3161 // reused. See http://crbug.com/544255.
3162 for (int i = 0; i < 2; ++i) {
3163 HttpRequestInfo request;
3164 request.method = "GET";
3165 request.url = GURL("https://www.example.org/");
3166 // Ensure that proxy authentication is attempted even
3167 // when the no authentication data flag is set.
3168 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013169
mmenked39192ee2015-12-09 00:57:233170 // Configure against proxy server "myproxy:70".
3171 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3172 BoundTestNetLog log;
3173 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013175
bnc691fda62016-08-12 00:43:163176 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013177
mmenked39192ee2015-12-09 00:57:233178 // Since we have proxy, should try to establish tunnel.
3179 MockWrite data_writes1[] = {
3180 MockWrite(ASYNC, 0,
3181 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3182 "Host: www.example.org:443\r\n"
3183 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013184
bnc691fda62016-08-12 00:43:163185 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233186 // be issuing -- the final header line contains the credentials.
3187 MockWrite(ASYNC, 3,
3188 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3189 "Host: www.example.org:443\r\n"
3190 "Proxy-Connection: keep-alive\r\n"
3191 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3192 };
ttuttle34f63b52015-03-05 04:33:013193
mmenked39192ee2015-12-09 00:57:233194 // The proxy responds to the connect with a 407, using a persistent
3195 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3196 MockRead data_reads1[] = {
3197 // No credentials.
3198 MockRead(ASYNC, 1,
3199 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3200 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3201 "Proxy-Connection: keep-alive\r\n"
3202 "Content-Length: 10\r\n\r\n"),
3203 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013204
mmenked39192ee2015-12-09 00:57:233205 // Wrong credentials (wrong password).
3206 MockRead(ASYNC, 4,
3207 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3208 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3209 "Proxy-Connection: keep-alive\r\n"
3210 "Content-Length: 10\r\n\r\n"),
3211 // No response body because the test stops reading here.
3212 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3213 };
ttuttle34f63b52015-03-05 04:33:013214
mmenked39192ee2015-12-09 00:57:233215 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3216 arraysize(data_writes1));
3217 data1.set_busy_before_sync_reads(true);
3218 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013219
mmenked39192ee2015-12-09 00:57:233220 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013221
bnc691fda62016-08-12 00:43:163222 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013223 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013224
mmenked39192ee2015-12-09 00:57:233225 TestNetLogEntry::List entries;
3226 log.GetEntries(&entries);
3227 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003228 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3229 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233230 ExpectLogContainsSomewhere(
3231 entries, pos,
mikecirone8b85c432016-09-08 19:11:003232 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3233 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013234
bnc691fda62016-08-12 00:43:163235 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233236 ASSERT_TRUE(response);
3237 ASSERT_TRUE(response->headers);
3238 EXPECT_TRUE(response->headers->IsKeepAlive());
3239 EXPECT_EQ(407, response->headers->response_code());
3240 EXPECT_EQ(10, response->headers->GetContentLength());
3241 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3242 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013243
mmenked39192ee2015-12-09 00:57:233244 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013245
mmenked39192ee2015-12-09 00:57:233246 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163247 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3248 callback2.callback());
robpercival214763f2016-07-01 23:27:013249 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013250
bnc691fda62016-08-12 00:43:163251 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233252 ASSERT_TRUE(response);
3253 ASSERT_TRUE(response->headers);
3254 EXPECT_TRUE(response->headers->IsKeepAlive());
3255 EXPECT_EQ(407, response->headers->response_code());
3256 EXPECT_EQ(10, response->headers->GetContentLength());
3257 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3258 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013259
mmenked39192ee2015-12-09 00:57:233260 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3261 // out of scope.
3262 session->CloseAllConnections();
3263 }
ttuttle34f63b52015-03-05 04:33:013264}
3265
3266// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3267// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013268TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233269 // On the second pass, the body read of the auth challenge is synchronous, so
3270 // IsConnectedAndIdle returns false. The socket should still be drained and
3271 // reused. See http://crbug.com/544255.
3272 for (int i = 0; i < 2; ++i) {
3273 HttpRequestInfo request;
3274 request.method = "GET";
3275 request.url = GURL("https://www.example.org/");
3276 // Ensure that proxy authentication is attempted even
3277 // when the no authentication data flag is set.
3278 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3279
3280 // Configure against proxy server "myproxy:70".
3281 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3282 BoundTestNetLog log;
3283 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233285
bnc691fda62016-08-12 00:43:163286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233287
3288 // Since we have proxy, should try to establish tunnel.
3289 MockWrite data_writes1[] = {
3290 MockWrite(ASYNC, 0,
3291 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3292 "Host: www.example.org:443\r\n"
3293 "Proxy-Connection: keep-alive\r\n\r\n"),
3294
bnc691fda62016-08-12 00:43:163295 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233296 // be issuing -- the final header line contains the credentials.
3297 MockWrite(ASYNC, 3,
3298 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3299 "Host: www.example.org:443\r\n"
3300 "Proxy-Connection: keep-alive\r\n"
3301 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3302 };
3303
3304 // The proxy responds to the connect with a 407, using a persistent
3305 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3306 MockRead data_reads1[] = {
3307 // No credentials.
3308 MockRead(ASYNC, 1,
3309 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3310 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3311 "Content-Length: 10\r\n\r\n"),
3312 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3313
3314 // Wrong credentials (wrong password).
3315 MockRead(ASYNC, 4,
3316 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3317 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3318 "Content-Length: 10\r\n\r\n"),
3319 // No response body because the test stops reading here.
3320 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3321 };
3322
3323 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3324 arraysize(data_writes1));
3325 data1.set_busy_before_sync_reads(true);
3326 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3327
3328 TestCompletionCallback callback1;
3329
bnc691fda62016-08-12 00:43:163330 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013331 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233332
3333 TestNetLogEntry::List entries;
3334 log.GetEntries(&entries);
3335 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003336 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3337 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233338 ExpectLogContainsSomewhere(
3339 entries, pos,
mikecirone8b85c432016-09-08 19:11:003340 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3341 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233342
bnc691fda62016-08-12 00:43:163343 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233344 ASSERT_TRUE(response);
3345 ASSERT_TRUE(response->headers);
3346 EXPECT_TRUE(response->headers->IsKeepAlive());
3347 EXPECT_EQ(407, response->headers->response_code());
3348 EXPECT_EQ(10, response->headers->GetContentLength());
3349 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3350 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3351
3352 TestCompletionCallback callback2;
3353
3354 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163355 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3356 callback2.callback());
robpercival214763f2016-07-01 23:27:013357 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233358
bnc691fda62016-08-12 00:43:163359 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233360 ASSERT_TRUE(response);
3361 ASSERT_TRUE(response->headers);
3362 EXPECT_TRUE(response->headers->IsKeepAlive());
3363 EXPECT_EQ(407, response->headers->response_code());
3364 EXPECT_EQ(10, response->headers->GetContentLength());
3365 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3366 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3367
3368 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3369 // out of scope.
3370 session->CloseAllConnections();
3371 }
3372}
3373
3374// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3375// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3376// the case the server sends extra data on the original socket, so it can't be
3377// reused.
bncd16676a2016-07-20 16:23:013378TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273379 HttpRequestInfo request;
3380 request.method = "GET";
bncce36dca22015-04-21 22:11:233381 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273382 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293383 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273384
[email protected]2d2697f92009-02-18 21:00:323385 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233386 session_deps_.proxy_service =
3387 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513388 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073389 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323391
[email protected]2d2697f92009-02-18 21:00:323392 // Since we have proxy, should try to establish tunnel.
3393 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233394 MockWrite(ASYNC, 0,
3395 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173396 "Host: www.example.org:443\r\n"
3397 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233398 };
[email protected]2d2697f92009-02-18 21:00:323399
mmenked39192ee2015-12-09 00:57:233400 // The proxy responds to the connect with a 407, using a persistent, but sends
3401 // extra data, so the socket cannot be reused.
3402 MockRead data_reads1[] = {
3403 // No credentials.
3404 MockRead(ASYNC, 1,
3405 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3406 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3407 "Content-Length: 10\r\n\r\n"),
3408 MockRead(SYNCHRONOUS, 2, "0123456789"),
3409 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3410 };
3411
3412 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233413 // After calling trans->RestartWithAuth(), this is the request we should
3414 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233415 MockWrite(ASYNC, 0,
3416 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173417 "Host: www.example.org:443\r\n"
3418 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233419 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3420
3421 MockWrite(ASYNC, 2,
3422 "GET / HTTP/1.1\r\n"
3423 "Host: www.example.org\r\n"
3424 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323425 };
3426
mmenked39192ee2015-12-09 00:57:233427 MockRead data_reads2[] = {
3428 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323429
mmenked39192ee2015-12-09 00:57:233430 MockRead(ASYNC, 3,
3431 "HTTP/1.1 200 OK\r\n"
3432 "Content-Type: text/html; charset=iso-8859-1\r\n"
3433 "Content-Length: 5\r\n\r\n"),
3434 // No response body because the test stops reading here.
3435 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323436 };
3437
mmenked39192ee2015-12-09 00:57:233438 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3439 arraysize(data_writes1));
3440 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073441 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233442 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3443 arraysize(data_writes2));
3444 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3445 SSLSocketDataProvider ssl(ASYNC, OK);
3446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323447
[email protected]49639fa2011-12-20 23:22:413448 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323449
bnc87dcefc2017-05-25 12:47:583450 auto trans =
3451 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323452
mmenked39192ee2015-12-09 00:57:233453 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013454 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233455
mmenke43758e62015-05-04 21:09:463456 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403457 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393458 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003459 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3460 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393461 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403462 entries, pos,
mikecirone8b85c432016-09-08 19:11:003463 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3464 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323465
[email protected]1c773ea12009-04-28 19:58:423466 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243467 ASSERT_TRUE(response);
3468 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323469 EXPECT_TRUE(response->headers->IsKeepAlive());
3470 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423471 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043472 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323473
mmenked39192ee2015-12-09 00:57:233474 LoadTimingInfo load_timing_info;
3475 // CONNECT requests and responses are handled at the connect job level, so
3476 // the transaction does not yet have a connection.
3477 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3478
[email protected]49639fa2011-12-20 23:22:413479 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323480
mmenked39192ee2015-12-09 00:57:233481 rv =
3482 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013483 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323484
[email protected]2d2697f92009-02-18 21:00:323485 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233486 EXPECT_EQ(200, response->headers->response_code());
3487 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423488 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133489
mmenked39192ee2015-12-09 00:57:233490 // The password prompt info should not be set.
3491 EXPECT_FALSE(response->auth_challenge);
3492
3493 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3494 TestLoadTimingNotReusedWithPac(load_timing_info,
3495 CONNECT_TIMING_HAS_SSL_TIMES);
3496
3497 trans.reset();
[email protected]102e27c2011-02-23 01:01:313498 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323499}
3500
mmenkee71e15332015-10-07 16:39:543501// Test the case a proxy closes a socket while the challenge body is being
3502// drained.
bncd16676a2016-07-20 16:23:013503TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543504 HttpRequestInfo request;
3505 request.method = "GET";
3506 request.url = GURL("https://www.example.org/");
3507 // Ensure that proxy authentication is attempted even
3508 // when the no authentication data flag is set.
3509 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3510
3511 // Configure against proxy server "myproxy:70".
3512 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093513 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543514
bnc691fda62016-08-12 00:43:163515 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543516
3517 // Since we have proxy, should try to establish tunnel.
3518 MockWrite data_writes1[] = {
3519 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173520 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543521 "Proxy-Connection: keep-alive\r\n\r\n"),
3522 };
3523
3524 // The proxy responds to the connect with a 407, using a persistent
3525 // connection.
3526 MockRead data_reads1[] = {
3527 // No credentials.
3528 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3529 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3530 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3531 // Server hands up in the middle of the body.
3532 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3533 };
3534
3535 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163536 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543537 // be issuing -- the final header line contains the credentials.
3538 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173539 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543540 "Proxy-Connection: keep-alive\r\n"
3541 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3542
3543 MockWrite("GET / HTTP/1.1\r\n"
3544 "Host: www.example.org\r\n"
3545 "Connection: keep-alive\r\n\r\n"),
3546 };
3547
3548 MockRead data_reads2[] = {
3549 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3550
3551 MockRead("HTTP/1.1 200 OK\r\n"),
3552 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3553 MockRead("Content-Length: 5\r\n\r\n"),
3554 MockRead(SYNCHRONOUS, "hello"),
3555 };
3556
3557 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3558 data_writes1, arraysize(data_writes1));
3559 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3560 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3561 data_writes2, arraysize(data_writes2));
3562 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3563 SSLSocketDataProvider ssl(ASYNC, OK);
3564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3565
3566 TestCompletionCallback callback;
3567
tfarina42834112016-09-22 13:38:203568 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013569 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543570
bnc691fda62016-08-12 00:43:163571 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543572 ASSERT_TRUE(response);
3573 ASSERT_TRUE(response->headers);
3574 EXPECT_TRUE(response->headers->IsKeepAlive());
3575 EXPECT_EQ(407, response->headers->response_code());
3576 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3577
bnc691fda62016-08-12 00:43:163578 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013579 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543580
bnc691fda62016-08-12 00:43:163581 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543582 ASSERT_TRUE(response);
3583 ASSERT_TRUE(response->headers);
3584 EXPECT_TRUE(response->headers->IsKeepAlive());
3585 EXPECT_EQ(200, response->headers->response_code());
3586 std::string body;
bnc691fda62016-08-12 00:43:163587 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543588 EXPECT_EQ("hello", body);
3589}
3590
[email protected]a8e9b162009-03-12 00:06:443591// Test that we don't read the response body when we fail to establish a tunnel,
3592// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013593TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273594 HttpRequestInfo request;
3595 request.method = "GET";
bncce36dca22015-04-21 22:11:233596 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273597
[email protected]a8e9b162009-03-12 00:06:443598 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033599 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443600
danakj1fd259a02016-04-16 03:17:093601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443602
bnc691fda62016-08-12 00:43:163603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443604
[email protected]a8e9b162009-03-12 00:06:443605 // Since we have proxy, should try to establish tunnel.
3606 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173607 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3608 "Host: www.example.org:443\r\n"
3609 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443610 };
3611
3612 // The proxy responds to the connect with a 407.
3613 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243614 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3615 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3616 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233617 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243618 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443619 };
3620
[email protected]31a2bfe2010-02-09 08:03:393621 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3622 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443624
[email protected]49639fa2011-12-20 23:22:413625 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443626
tfarina42834112016-09-22 13:38:203627 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443629
3630 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013631 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443632
bnc691fda62016-08-12 00:43:163633 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243634 ASSERT_TRUE(response);
3635 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443636 EXPECT_TRUE(response->headers->IsKeepAlive());
3637 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423638 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443639
3640 std::string response_data;
bnc691fda62016-08-12 00:43:163641 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013642 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183643
3644 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313645 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443646}
3647
ttuttle7933c112015-01-06 00:55:243648// Test that we don't pass extraneous headers from the proxy's response to the
3649// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013650TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243651 HttpRequestInfo request;
3652 request.method = "GET";
bncce36dca22015-04-21 22:11:233653 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243654
3655 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033656 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243657
danakj1fd259a02016-04-16 03:17:093658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243659
bnc691fda62016-08-12 00:43:163660 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243661
3662 // Since we have proxy, should try to establish tunnel.
3663 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173664 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3665 "Host: www.example.org:443\r\n"
3666 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243667 };
3668
3669 // The proxy responds to the connect with a 407.
3670 MockRead data_reads[] = {
3671 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3672 MockRead("X-Foo: bar\r\n"),
3673 MockRead("Set-Cookie: foo=bar\r\n"),
3674 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3675 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233676 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243677 };
3678
3679 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3680 arraysize(data_writes));
3681 session_deps_.socket_factory->AddSocketDataProvider(&data);
3682
3683 TestCompletionCallback callback;
3684
tfarina42834112016-09-22 13:38:203685 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243687
3688 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013689 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243690
bnc691fda62016-08-12 00:43:163691 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243692 ASSERT_TRUE(response);
3693 ASSERT_TRUE(response->headers);
3694 EXPECT_TRUE(response->headers->IsKeepAlive());
3695 EXPECT_EQ(407, response->headers->response_code());
3696 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3697 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3698 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3699
3700 std::string response_data;
bnc691fda62016-08-12 00:43:163701 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013702 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243703
3704 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3705 session->CloseAllConnections();
3706}
3707
[email protected]8fdbcd22010-05-05 02:54:523708// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3709// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013710TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523711 HttpRequestInfo request;
3712 request.method = "GET";
bncce36dca22015-04-21 22:11:233713 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523714
[email protected]cb9bf6ca2011-01-28 13:15:273715 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273718
[email protected]8fdbcd22010-05-05 02:54:523719 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233720 MockWrite(
3721 "GET / HTTP/1.1\r\n"
3722 "Host: www.example.org\r\n"
3723 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523724 };
3725
3726 MockRead data_reads1[] = {
3727 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3728 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3729 // Large content-length -- won't matter, as connection will be reset.
3730 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063731 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523732 };
3733
3734 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3735 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523737
[email protected]49639fa2011-12-20 23:22:413738 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523739
tfarina42834112016-09-22 13:38:203740 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523742
3743 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013744 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523745}
3746
[email protected]7a67a8152010-11-05 18:31:103747// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3748// through a non-authenticating proxy. The request should fail with
3749// ERR_UNEXPECTED_PROXY_AUTH.
3750// Note that it is impossible to detect if an HTTP server returns a 407 through
3751// a non-authenticating proxy - there is nothing to indicate whether the
3752// response came from the proxy or the server, so it is treated as if the proxy
3753// issued the challenge.
bncd16676a2016-07-20 16:23:013754TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273755 HttpRequestInfo request;
3756 request.method = "GET";
bncce36dca22015-04-21 22:11:233757 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273758
rdsmith82957ad2015-09-16 19:42:033759 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513760 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073761 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103763
[email protected]7a67a8152010-11-05 18:31:103764 // Since we have proxy, should try to establish tunnel.
3765 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173766 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3767 "Host: www.example.org:443\r\n"
3768 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103769
rsleevidb16bb02015-11-12 23:47:173770 MockWrite("GET / HTTP/1.1\r\n"
3771 "Host: www.example.org\r\n"
3772 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103773 };
3774
3775 MockRead data_reads1[] = {
3776 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3777
3778 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3779 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3780 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063781 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103782 };
3783
3784 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3785 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073786 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063787 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073788 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103789
[email protected]49639fa2011-12-20 23:22:413790 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103791
bnc691fda62016-08-12 00:43:163792 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103793
bnc691fda62016-08-12 00:43:163794 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103796
3797 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013798 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463799 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403800 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103801 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003802 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3803 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103804 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403805 entries, pos,
mikecirone8b85c432016-09-08 19:11:003806 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3807 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103808}
[email protected]2df19bb2010-08-25 20:13:463809
mmenke2a1781d2015-10-07 19:25:333810// Test a proxy auth scheme that allows default credentials and a proxy server
3811// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013812TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333813 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3814 HttpRequestInfo request;
3815 request.method = "GET";
3816 request.url = GURL("https://www.example.org/");
3817
3818 // Configure against proxy server "myproxy:70".
3819 session_deps_.proxy_service =
3820 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3821
bnc87dcefc2017-05-25 12:47:583822 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333823 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583824 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333825 mock_handler->set_allows_default_credentials(true);
3826 auth_handler_factory->AddMockHandler(mock_handler.release(),
3827 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483828 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333829
3830 // Add NetLog just so can verify load timing information gets a NetLog ID.
3831 NetLog net_log;
3832 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093833 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333834
3835 // Since we have proxy, should try to establish tunnel.
3836 MockWrite data_writes1[] = {
3837 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173838 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333839 "Proxy-Connection: keep-alive\r\n\r\n"),
3840 };
3841
3842 // The proxy responds to the connect with a 407, using a non-persistent
3843 // connection.
3844 MockRead data_reads1[] = {
3845 // No credentials.
3846 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3847 MockRead("Proxy-Authenticate: Mock\r\n"),
3848 MockRead("Proxy-Connection: close\r\n\r\n"),
3849 };
3850
3851 // Since the first connection couldn't be reused, need to establish another
3852 // once given credentials.
3853 MockWrite data_writes2[] = {
3854 // After calling trans->RestartWithAuth(), this is the request we should
3855 // be issuing -- the final header line contains the credentials.
3856 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173857 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333858 "Proxy-Connection: keep-alive\r\n"
3859 "Proxy-Authorization: auth_token\r\n\r\n"),
3860
3861 MockWrite("GET / HTTP/1.1\r\n"
3862 "Host: www.example.org\r\n"
3863 "Connection: keep-alive\r\n\r\n"),
3864 };
3865
3866 MockRead data_reads2[] = {
3867 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3868
3869 MockRead("HTTP/1.1 200 OK\r\n"),
3870 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3871 MockRead("Content-Length: 5\r\n\r\n"),
3872 MockRead(SYNCHRONOUS, "hello"),
3873 };
3874
3875 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3876 data_writes1, arraysize(data_writes1));
3877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3878 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3879 data_writes2, arraysize(data_writes2));
3880 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3881 SSLSocketDataProvider ssl(ASYNC, OK);
3882 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3883
bnc87dcefc2017-05-25 12:47:583884 auto trans =
3885 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333886
3887 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203888 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013889 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333890
3891 const HttpResponseInfo* response = trans->GetResponseInfo();
3892 ASSERT_TRUE(response);
3893 ASSERT_TRUE(response->headers);
3894 EXPECT_FALSE(response->headers->IsKeepAlive());
3895 EXPECT_EQ(407, response->headers->response_code());
3896 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3897 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523898 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333899
3900 LoadTimingInfo load_timing_info;
3901 // CONNECT requests and responses are handled at the connect job level, so
3902 // the transaction does not yet have a connection.
3903 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3904
3905 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013906 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333907 response = trans->GetResponseInfo();
3908 ASSERT_TRUE(response);
3909 ASSERT_TRUE(response->headers);
3910 EXPECT_TRUE(response->headers->IsKeepAlive());
3911 EXPECT_EQ(200, response->headers->response_code());
3912 EXPECT_EQ(5, response->headers->GetContentLength());
3913 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3914
3915 // The password prompt info should not be set.
3916 EXPECT_FALSE(response->auth_challenge);
3917
3918 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3919 TestLoadTimingNotReusedWithPac(load_timing_info,
3920 CONNECT_TIMING_HAS_SSL_TIMES);
3921
3922 trans.reset();
3923 session->CloseAllConnections();
3924}
3925
3926// Test a proxy auth scheme that allows default credentials and a proxy server
3927// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013928TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333929 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3930 HttpRequestInfo request;
3931 request.method = "GET";
3932 request.url = GURL("https://www.example.org/");
3933
3934 // Configure against proxy server "myproxy:70".
3935 session_deps_.proxy_service =
3936 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3937
bnc87dcefc2017-05-25 12:47:583938 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333939 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583940 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333941 mock_handler->set_allows_default_credentials(true);
3942 auth_handler_factory->AddMockHandler(mock_handler.release(),
3943 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483944 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333945
3946 // Add NetLog just so can verify load timing information gets a NetLog ID.
3947 NetLog net_log;
3948 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093949 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333950
3951 // Should try to establish tunnel.
3952 MockWrite data_writes1[] = {
3953 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173954 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333955 "Proxy-Connection: keep-alive\r\n\r\n"),
3956
3957 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173958 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333959 "Proxy-Connection: keep-alive\r\n"
3960 "Proxy-Authorization: auth_token\r\n\r\n"),
3961 };
3962
3963 // The proxy responds to the connect with a 407, using a non-persistent
3964 // connection.
3965 MockRead data_reads1[] = {
3966 // No credentials.
3967 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3968 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3969 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3970 };
3971
3972 // Since the first connection was closed, need to establish another once given
3973 // credentials.
3974 MockWrite data_writes2[] = {
3975 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173976 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333977 "Proxy-Connection: keep-alive\r\n"
3978 "Proxy-Authorization: auth_token\r\n\r\n"),
3979
3980 MockWrite("GET / HTTP/1.1\r\n"
3981 "Host: www.example.org\r\n"
3982 "Connection: keep-alive\r\n\r\n"),
3983 };
3984
3985 MockRead data_reads2[] = {
3986 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3987
3988 MockRead("HTTP/1.1 200 OK\r\n"),
3989 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3990 MockRead("Content-Length: 5\r\n\r\n"),
3991 MockRead(SYNCHRONOUS, "hello"),
3992 };
3993
3994 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3995 data_writes1, arraysize(data_writes1));
3996 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3997 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3998 data_writes2, arraysize(data_writes2));
3999 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4000 SSLSocketDataProvider ssl(ASYNC, OK);
4001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4002
bnc87dcefc2017-05-25 12:47:584003 auto trans =
4004 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334005
4006 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204007 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014008 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334009
4010 const HttpResponseInfo* response = trans->GetResponseInfo();
4011 ASSERT_TRUE(response);
4012 ASSERT_TRUE(response->headers);
4013 EXPECT_TRUE(response->headers->IsKeepAlive());
4014 EXPECT_EQ(407, response->headers->response_code());
4015 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4016 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4017 EXPECT_FALSE(response->auth_challenge);
4018
4019 LoadTimingInfo load_timing_info;
4020 // CONNECT requests and responses are handled at the connect job level, so
4021 // the transaction does not yet have a connection.
4022 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4023
4024 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014025 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334026
4027 response = trans->GetResponseInfo();
4028 ASSERT_TRUE(response);
4029 ASSERT_TRUE(response->headers);
4030 EXPECT_TRUE(response->headers->IsKeepAlive());
4031 EXPECT_EQ(200, response->headers->response_code());
4032 EXPECT_EQ(5, response->headers->GetContentLength());
4033 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4034
4035 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524036 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334037
4038 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4039 TestLoadTimingNotReusedWithPac(load_timing_info,
4040 CONNECT_TIMING_HAS_SSL_TIMES);
4041
4042 trans.reset();
4043 session->CloseAllConnections();
4044}
4045
4046// Test a proxy auth scheme that allows default credentials and a proxy server
4047// that hangs up when credentials are initially sent, and hangs up again when
4048// they are retried.
bncd16676a2016-07-20 16:23:014049TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334050 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4051 HttpRequestInfo request;
4052 request.method = "GET";
4053 request.url = GURL("https://www.example.org/");
4054
4055 // Configure against proxy server "myproxy:70".
4056 session_deps_.proxy_service =
4057 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4058
bnc87dcefc2017-05-25 12:47:584059 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334060 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584061 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334062 mock_handler->set_allows_default_credentials(true);
4063 auth_handler_factory->AddMockHandler(mock_handler.release(),
4064 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484065 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334066
4067 // Add NetLog just so can verify load timing information gets a NetLog ID.
4068 NetLog net_log;
4069 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094070 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334071
4072 // Should try to establish tunnel.
4073 MockWrite data_writes1[] = {
4074 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174075 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334076 "Proxy-Connection: keep-alive\r\n\r\n"),
4077
4078 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174079 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334080 "Proxy-Connection: keep-alive\r\n"
4081 "Proxy-Authorization: auth_token\r\n\r\n"),
4082 };
4083
4084 // The proxy responds to the connect with a 407, and then hangs up after the
4085 // second request is sent.
4086 MockRead data_reads1[] = {
4087 // No credentials.
4088 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4089 MockRead("Content-Length: 0\r\n"),
4090 MockRead("Proxy-Connection: keep-alive\r\n"),
4091 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4092 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4093 };
4094
4095 // HttpNetworkTransaction sees a reused connection that was closed with
4096 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4097 // request.
4098 MockWrite data_writes2[] = {
4099 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174100 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334101 "Proxy-Connection: keep-alive\r\n\r\n"),
4102 };
4103
4104 // The proxy, having had more than enough of us, just hangs up.
4105 MockRead data_reads2[] = {
4106 // No credentials.
4107 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4108 };
4109
4110 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4111 data_writes1, arraysize(data_writes1));
4112 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4113 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4114 data_writes2, arraysize(data_writes2));
4115 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4116
bnc87dcefc2017-05-25 12:47:584117 auto trans =
4118 base::MakeUnique<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 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4135
4136 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014137 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334138
4139 trans.reset();
4140 session->CloseAllConnections();
4141}
4142
4143// Test a proxy auth scheme that allows default credentials and a proxy server
4144// that hangs up when credentials are initially sent, and sends a challenge
4145// again they are retried.
bncd16676a2016-07-20 16:23:014146TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334147 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4148 HttpRequestInfo request;
4149 request.method = "GET";
4150 request.url = GURL("https://www.example.org/");
4151
4152 // Configure against proxy server "myproxy:70".
4153 session_deps_.proxy_service =
4154 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4155
bnc87dcefc2017-05-25 12:47:584156 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334157 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584158 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334159 mock_handler->set_allows_default_credentials(true);
4160 auth_handler_factory->AddMockHandler(mock_handler.release(),
4161 HttpAuth::AUTH_PROXY);
4162 // Add another handler for the second challenge. It supports default
4163 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584164 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334165 mock_handler->set_allows_default_credentials(true);
4166 auth_handler_factory->AddMockHandler(mock_handler.release(),
4167 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484168 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334169
4170 // Add NetLog just so can verify load timing information gets a NetLog ID.
4171 NetLog net_log;
4172 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094173 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334174
4175 // Should try to establish tunnel.
4176 MockWrite data_writes1[] = {
4177 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174178 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334179 "Proxy-Connection: keep-alive\r\n\r\n"),
4180 };
4181
4182 // The proxy responds to the connect with a 407, using a non-persistent
4183 // connection.
4184 MockRead data_reads1[] = {
4185 // No credentials.
4186 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4187 MockRead("Proxy-Authenticate: Mock\r\n"),
4188 MockRead("Proxy-Connection: close\r\n\r\n"),
4189 };
4190
4191 // Since the first connection was closed, need to establish another once given
4192 // credentials.
4193 MockWrite data_writes2[] = {
4194 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174195 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334196 "Proxy-Connection: keep-alive\r\n"
4197 "Proxy-Authorization: auth_token\r\n\r\n"),
4198 };
4199
4200 MockRead data_reads2[] = {
4201 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4202 MockRead("Proxy-Authenticate: Mock\r\n"),
4203 MockRead("Proxy-Connection: close\r\n\r\n"),
4204 };
4205
4206 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4207 data_writes1, arraysize(data_writes1));
4208 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4209 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4210 data_writes2, arraysize(data_writes2));
4211 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4212 SSLSocketDataProvider ssl(ASYNC, OK);
4213 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4214
bnc87dcefc2017-05-25 12:47:584215 auto trans =
4216 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334217
4218 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204219 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014220 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334221
4222 const HttpResponseInfo* response = trans->GetResponseInfo();
4223 ASSERT_TRUE(response);
4224 ASSERT_TRUE(response->headers);
4225 EXPECT_EQ(407, response->headers->response_code());
4226 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4227 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4228 EXPECT_FALSE(response->auth_challenge);
4229
4230 LoadTimingInfo load_timing_info;
4231 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4232
4233 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014234 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334235 response = trans->GetResponseInfo();
4236 ASSERT_TRUE(response);
4237 ASSERT_TRUE(response->headers);
4238 EXPECT_EQ(407, response->headers->response_code());
4239 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4240 EXPECT_TRUE(response->auth_challenge);
4241
4242 trans.reset();
4243 session->CloseAllConnections();
4244}
4245
asankae2257db2016-10-11 22:03:164246// A more nuanced test than GenerateAuthToken test which asserts that
4247// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4248// unnecessarily invalidated, and that if the server co-operates, the
4249// authentication handshake can continue with the same scheme but with a
4250// different identity.
4251TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4252 HttpRequestInfo request;
4253 request.method = "GET";
4254 request.url = GURL("http://www.example.org/");
4255
bnc87dcefc2017-05-25 12:47:584256 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164257 auth_handler_factory->set_do_init_from_challenge(true);
4258
4259 // First handler. Uses default credentials, but barfs at generate auth token.
bnc87dcefc2017-05-25 12:47:584260 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164261 mock_handler->set_allows_default_credentials(true);
4262 mock_handler->set_allows_explicit_credentials(true);
4263 mock_handler->set_connection_based(true);
4264 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4265 auth_handler_factory->AddMockHandler(mock_handler.release(),
4266 HttpAuth::AUTH_SERVER);
4267
4268 // Add another handler for the second challenge. It supports default
4269 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584270 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164271 mock_handler->set_allows_default_credentials(true);
4272 mock_handler->set_allows_explicit_credentials(true);
4273 mock_handler->set_connection_based(true);
4274 auth_handler_factory->AddMockHandler(mock_handler.release(),
4275 HttpAuth::AUTH_SERVER);
4276 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4277
4278 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4279
4280 MockWrite data_writes1[] = {
4281 MockWrite("GET / HTTP/1.1\r\n"
4282 "Host: www.example.org\r\n"
4283 "Connection: keep-alive\r\n\r\n"),
4284 };
4285
4286 MockRead data_reads1[] = {
4287 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4288 "WWW-Authenticate: Mock\r\n"
4289 "Connection: keep-alive\r\n\r\n"),
4290 };
4291
4292 // Identical to data_writes1[]. The AuthHandler encounters a
4293 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4294 // transaction procceds without an authorization header.
4295 MockWrite data_writes2[] = {
4296 MockWrite("GET / HTTP/1.1\r\n"
4297 "Host: www.example.org\r\n"
4298 "Connection: keep-alive\r\n\r\n"),
4299 };
4300
4301 MockRead data_reads2[] = {
4302 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4303 "WWW-Authenticate: Mock\r\n"
4304 "Connection: keep-alive\r\n\r\n"),
4305 };
4306
4307 MockWrite data_writes3[] = {
4308 MockWrite("GET / HTTP/1.1\r\n"
4309 "Host: www.example.org\r\n"
4310 "Connection: keep-alive\r\n"
4311 "Authorization: auth_token\r\n\r\n"),
4312 };
4313
4314 MockRead data_reads3[] = {
4315 MockRead("HTTP/1.1 200 OK\r\n"
4316 "Content-Length: 5\r\n"
4317 "Content-Type: text/plain\r\n"
4318 "Connection: keep-alive\r\n\r\n"
4319 "Hello"),
4320 };
4321
4322 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4323 data_writes1, arraysize(data_writes1));
4324 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4325
4326 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4327 data_writes2, arraysize(data_writes2));
4328 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4329
4330 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4331 data_writes3, arraysize(data_writes3));
4332 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4333
bnc87dcefc2017-05-25 12:47:584334 auto trans =
4335 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164336
4337 TestCompletionCallback callback;
4338 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4339 EXPECT_THAT(callback.GetResult(rv), IsOk());
4340
4341 const HttpResponseInfo* response = trans->GetResponseInfo();
4342 ASSERT_TRUE(response);
4343 ASSERT_TRUE(response->headers);
4344 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4345
4346 // The following three tests assert that an authentication challenge was
4347 // received and that the stack is ready to respond to the challenge using
4348 // ambient credentials.
4349 EXPECT_EQ(401, response->headers->response_code());
4350 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4351 EXPECT_FALSE(response->auth_challenge);
4352
4353 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4354 EXPECT_THAT(callback.GetResult(rv), IsOk());
4355 response = trans->GetResponseInfo();
4356 ASSERT_TRUE(response);
4357 ASSERT_TRUE(response->headers);
4358
4359 // The following three tests assert that an authentication challenge was
4360 // received and that the stack needs explicit credentials before it is ready
4361 // to respond to the challenge.
4362 EXPECT_EQ(401, response->headers->response_code());
4363 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4364 EXPECT_TRUE(response->auth_challenge);
4365
4366 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4367 EXPECT_THAT(callback.GetResult(rv), IsOk());
4368 response = trans->GetResponseInfo();
4369 ASSERT_TRUE(response);
4370 ASSERT_TRUE(response->headers);
4371 EXPECT_EQ(200, response->headers->response_code());
4372
4373 trans.reset();
4374 session->CloseAllConnections();
4375}
4376
[email protected]029c83b62013-01-24 05:28:204377// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014378TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204379 HttpRequestInfo request1;
4380 request1.method = "GET";
bncce36dca22015-04-21 22:11:234381 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204382
4383 HttpRequestInfo request2;
4384 request2.method = "GET";
bncce36dca22015-04-21 22:11:234385 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204386
4387 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134388 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514389 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074390 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204392
4393 // Since we have proxy, should try to establish tunnel.
4394 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174395 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4396 "Host: www.example.org:443\r\n"
4397 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204398
rsleevidb16bb02015-11-12 23:47:174399 MockWrite("GET /1 HTTP/1.1\r\n"
4400 "Host: www.example.org\r\n"
4401 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204402
rsleevidb16bb02015-11-12 23:47:174403 MockWrite("GET /2 HTTP/1.1\r\n"
4404 "Host: www.example.org\r\n"
4405 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204406 };
4407
4408 // The proxy responds to the connect with a 407, using a persistent
4409 // connection.
4410 MockRead data_reads1[] = {
4411 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4412
4413 MockRead("HTTP/1.1 200 OK\r\n"),
4414 MockRead("Content-Length: 1\r\n\r\n"),
4415 MockRead(SYNCHRONOUS, "1"),
4416
4417 MockRead("HTTP/1.1 200 OK\r\n"),
4418 MockRead("Content-Length: 2\r\n\r\n"),
4419 MockRead(SYNCHRONOUS, "22"),
4420 };
4421
4422 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4423 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074424 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204425 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204427
4428 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584429 auto trans1 =
4430 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204431
4432 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204434
4435 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014436 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204437
4438 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524439 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474440 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524441 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204442 EXPECT_EQ(1, response1->headers->GetContentLength());
4443
4444 LoadTimingInfo load_timing_info1;
4445 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4446 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4447
4448 trans1.reset();
4449
4450 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584451 auto trans2 =
4452 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204453
4454 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204456
4457 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014458 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204459
4460 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524461 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474462 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524463 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204464 EXPECT_EQ(2, response2->headers->GetContentLength());
4465
4466 LoadTimingInfo load_timing_info2;
4467 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4468 TestLoadTimingReused(load_timing_info2);
4469
4470 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4471
4472 trans2.reset();
4473 session->CloseAllConnections();
4474}
4475
4476// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014477TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204478 HttpRequestInfo request1;
4479 request1.method = "GET";
bncce36dca22015-04-21 22:11:234480 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204481
4482 HttpRequestInfo request2;
4483 request2.method = "GET";
bncce36dca22015-04-21 22:11:234484 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204485
4486 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034487 session_deps_.proxy_service =
4488 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514489 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074490 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094491 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204492
4493 // Since we have proxy, should try to establish tunnel.
4494 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174495 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4496 "Host: www.example.org:443\r\n"
4497 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204498
rsleevidb16bb02015-11-12 23:47:174499 MockWrite("GET /1 HTTP/1.1\r\n"
4500 "Host: www.example.org\r\n"
4501 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204502
rsleevidb16bb02015-11-12 23:47:174503 MockWrite("GET /2 HTTP/1.1\r\n"
4504 "Host: www.example.org\r\n"
4505 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204506 };
4507
4508 // The proxy responds to the connect with a 407, using a persistent
4509 // connection.
4510 MockRead data_reads1[] = {
4511 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4512
4513 MockRead("HTTP/1.1 200 OK\r\n"),
4514 MockRead("Content-Length: 1\r\n\r\n"),
4515 MockRead(SYNCHRONOUS, "1"),
4516
4517 MockRead("HTTP/1.1 200 OK\r\n"),
4518 MockRead("Content-Length: 2\r\n\r\n"),
4519 MockRead(SYNCHRONOUS, "22"),
4520 };
4521
4522 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4523 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074524 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204525 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204527
4528 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584529 auto trans1 =
4530 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204531
4532 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204534
4535 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014536 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204537
4538 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524539 ASSERT_TRUE(response1);
4540 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204541 EXPECT_EQ(1, response1->headers->GetContentLength());
4542
4543 LoadTimingInfo load_timing_info1;
4544 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4545 TestLoadTimingNotReusedWithPac(load_timing_info1,
4546 CONNECT_TIMING_HAS_SSL_TIMES);
4547
4548 trans1.reset();
4549
4550 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584551 auto trans2 =
4552 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204553
4554 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204556
4557 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014558 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204559
4560 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524561 ASSERT_TRUE(response2);
4562 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204563 EXPECT_EQ(2, response2->headers->GetContentLength());
4564
4565 LoadTimingInfo load_timing_info2;
4566 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4567 TestLoadTimingReusedWithPac(load_timing_info2);
4568
4569 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4570
4571 trans2.reset();
4572 session->CloseAllConnections();
4573}
4574
[email protected]2df19bb2010-08-25 20:13:464575// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014576TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274577 HttpRequestInfo request;
4578 request.method = "GET";
bncce36dca22015-04-21 22:11:234579 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274580
[email protected]2df19bb2010-08-25 20:13:464581 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034582 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514583 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074584 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094585 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464586
[email protected]2df19bb2010-08-25 20:13:464587 // Since we have proxy, should use full url
4588 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234589 MockWrite(
4590 "GET http://www.example.org/ HTTP/1.1\r\n"
4591 "Host: www.example.org\r\n"
4592 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464593 };
4594
4595 MockRead data_reads1[] = {
4596 MockRead("HTTP/1.1 200 OK\r\n"),
4597 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4598 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064599 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464600 };
4601
4602 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4603 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074604 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064605 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464607
[email protected]49639fa2011-12-20 23:22:414608 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464609
bnc691fda62016-08-12 00:43:164610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504611
bnc691fda62016-08-12 00:43:164612 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464614
4615 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014616 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464617
[email protected]58e32bb2013-01-21 18:23:254618 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164619 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254620 TestLoadTimingNotReused(load_timing_info,
4621 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4622
bnc691fda62016-08-12 00:43:164623 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524624 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464625
tbansal2ecbbc72016-10-06 17:15:474626 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464627 EXPECT_TRUE(response->headers->IsKeepAlive());
4628 EXPECT_EQ(200, response->headers->response_code());
4629 EXPECT_EQ(100, response->headers->GetContentLength());
4630 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4631
4632 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524633 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464634}
4635
[email protected]7642b5ae2010-09-01 20:55:174636// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014637TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274638 HttpRequestInfo request;
4639 request.method = "GET";
bncce36dca22015-04-21 22:11:234640 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274641
[email protected]7642b5ae2010-09-01 20:55:174642 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034643 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514644 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074645 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174647
bncce36dca22015-04-21 22:11:234648 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414649 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454650 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414651 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174652
bnc42331402016-07-25 13:36:154653 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414654 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174655 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414656 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174657 };
4658
rch8e6c6c42015-05-01 14:05:134659 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4660 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074661 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174662
[email protected]8ddf8322012-02-23 18:08:064663 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364664 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074665 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174666
[email protected]49639fa2011-12-20 23:22:414667 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174668
bnc691fda62016-08-12 00:43:164669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504670
bnc691fda62016-08-12 00:43:164671 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174673
4674 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014675 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174676
[email protected]58e32bb2013-01-21 18:23:254677 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164678 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254679 TestLoadTimingNotReused(load_timing_info,
4680 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4681
bnc691fda62016-08-12 00:43:164682 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524683 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474684 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524685 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024686 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174687
4688 std::string response_data;
bnc691fda62016-08-12 00:43:164689 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234690 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174691}
4692
[email protected]1c173852014-06-19 12:51:504693// Verifies that a session which races and wins against the owning transaction
4694// (completing prior to host resolution), doesn't fail the transaction.
4695// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014696TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504697 HttpRequestInfo request;
4698 request.method = "GET";
bncce36dca22015-04-21 22:11:234699 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504700
4701 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034702 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514703 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504704 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504706
bncce36dca22015-04-21 22:11:234707 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414708 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454709 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414710 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504711
bnc42331402016-07-25 13:36:154712 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414713 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504714 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414715 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504716 };
4717
rch8e6c6c42015-05-01 14:05:134718 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4719 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504720 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4721
4722 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364723 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4725
4726 TestCompletionCallback callback1;
4727
bnc691fda62016-08-12 00:43:164728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504729
4730 // Stall the hostname resolution begun by the transaction.
4731 session_deps_.host_resolver->set_synchronous_mode(false);
4732 session_deps_.host_resolver->set_ondemand_mode(true);
4733
bnc691fda62016-08-12 00:43:164734 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504736
4737 // Race a session to the proxy, which completes first.
4738 session_deps_.host_resolver->set_ondemand_mode(false);
4739 SpdySessionKey key(
4740 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4741 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424742 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504743
4744 // Unstall the resolution begun by the transaction.
4745 session_deps_.host_resolver->set_ondemand_mode(true);
4746 session_deps_.host_resolver->ResolveAllPending();
4747
4748 EXPECT_FALSE(callback1.have_result());
4749 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014750 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504751
bnc691fda62016-08-12 00:43:164752 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524753 ASSERT_TRUE(response);
4754 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024755 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504756
4757 std::string response_data;
bnc691fda62016-08-12 00:43:164758 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504759 EXPECT_EQ(kUploadData, response_data);
4760}
4761
[email protected]dc7bd1c52010-11-12 00:01:134762// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014763TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274764 HttpRequestInfo request;
4765 request.method = "GET";
bncce36dca22015-04-21 22:11:234766 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274767
[email protected]79cb5c12011-09-12 13:12:044768 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034769 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514770 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074771 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134773
[email protected]dc7bd1c52010-11-12 00:01:134774 // The first request will be a bare GET, the second request will be a
4775 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454776 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414777 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494778 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384779 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134780 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464781 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134782 };
bncdf80d44fd2016-07-15 20:27:414783 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4784 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4785 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134786 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414787 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134788 };
4789
4790 // The first response is a 407 proxy authentication challenge, and the second
4791 // response will be a 200 response since the second request includes a valid
4792 // Authorization header.
4793 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464794 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134795 };
bnc42331402016-07-25 13:36:154796 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234797 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414798 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4799 SpdySerializedFrame body_authentication(
4800 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154801 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414802 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134803 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414804 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464805 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414806 CreateMockRead(resp_data, 4),
4807 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134808 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134809 };
4810
rch8e6c6c42015-05-01 14:05:134811 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4812 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074813 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134814
[email protected]8ddf8322012-02-23 18:08:064815 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364816 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074817 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134818
[email protected]49639fa2011-12-20 23:22:414819 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134820
bnc691fda62016-08-12 00:43:164821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134822
bnc691fda62016-08-12 00:43:164823 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134825
4826 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014827 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134828
bnc691fda62016-08-12 00:43:164829 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134830
wezca1070932016-05-26 20:30:524831 ASSERT_TRUE(response);
4832 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134833 EXPECT_EQ(407, response->headers->response_code());
4834 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434835 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134836
[email protected]49639fa2011-12-20 23:22:414837 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134838
bnc691fda62016-08-12 00:43:164839 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134841
4842 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014843 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134844
bnc691fda62016-08-12 00:43:164845 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134846
wezca1070932016-05-26 20:30:524847 ASSERT_TRUE(response_restart);
4848 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134849 EXPECT_EQ(200, response_restart->headers->response_code());
4850 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524851 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134852}
4853
[email protected]d9da5fe2010-10-13 22:37:164854// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014855TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274856 HttpRequestInfo request;
4857 request.method = "GET";
bncce36dca22015-04-21 22:11:234858 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274859
[email protected]d9da5fe2010-10-13 22:37:164860 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034861 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514862 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074863 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164865
bnc691fda62016-08-12 00:43:164866 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164867
bncce36dca22015-04-21 22:11:234868 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414869 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234870 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4871 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164872
bncce36dca22015-04-21 22:11:234873 const char get[] =
4874 "GET / HTTP/1.1\r\n"
4875 "Host: www.example.org\r\n"
4876 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414877 SpdySerializedFrame wrapped_get(
4878 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154879 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164880 const char resp[] = "HTTP/1.1 200 OK\r\n"
4881 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414882 SpdySerializedFrame wrapped_get_resp(
4883 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4884 SpdySerializedFrame wrapped_body(
4885 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4886 SpdySerializedFrame window_update(
4887 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044888
4889 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414890 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4891 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044892 };
4893
[email protected]d9da5fe2010-10-13 22:37:164894 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414895 CreateMockRead(conn_resp, 1, ASYNC),
4896 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4897 CreateMockRead(wrapped_body, 4, ASYNC),
4898 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134899 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164900 };
4901
rch8e6c6c42015-05-01 14:05:134902 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4903 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074904 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164905
[email protected]8ddf8322012-02-23 18:08:064906 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364907 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074908 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064909 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074910 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164911
[email protected]49639fa2011-12-20 23:22:414912 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164913
bnc691fda62016-08-12 00:43:164914 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164916
4917 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014918 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164919
[email protected]58e32bb2013-01-21 18:23:254920 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164921 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254922 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4923
bnc691fda62016-08-12 00:43:164924 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524925 ASSERT_TRUE(response);
4926 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164927 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4928
4929 std::string response_data;
bnc691fda62016-08-12 00:43:164930 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164931 EXPECT_EQ("1234567890", response_data);
4932}
4933
4934// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014935TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4936 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384937
[email protected]cb9bf6ca2011-01-28 13:15:274938 HttpRequestInfo request;
4939 request.method = "GET";
bncce36dca22015-04-21 22:11:234940 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274941
[email protected]d9da5fe2010-10-13 22:37:164942 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034943 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514944 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074945 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164947
bnc691fda62016-08-12 00:43:164948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164949
bncce36dca22015-04-21 22:11:234950 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414951 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234952 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4953 // fetch https://www.example.org/ via SPDY
4954 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414955 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494956 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414957 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154958 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414959 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154960 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414961 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024962 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414963 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4964 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024965 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414966 SpdySerializedFrame window_update_get_resp(
4967 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4968 SpdySerializedFrame window_update_body(
4969 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044970
4971 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414972 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4973 CreateMockWrite(window_update_get_resp, 6),
4974 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044975 };
4976
[email protected]d9da5fe2010-10-13 22:37:164977 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414978 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094979 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414980 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4981 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134982 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164983 };
4984
rch32320842015-05-16 15:57:094985 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4986 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074987 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164988
[email protected]8ddf8322012-02-23 18:08:064989 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364990 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074991 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064992 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364993 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164995
[email protected]49639fa2011-12-20 23:22:414996 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164997
bnc691fda62016-08-12 00:43:164998 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165000
rch32320842015-05-16 15:57:095001 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555002 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095003 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595004 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165005 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015006 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165007
[email protected]58e32bb2013-01-21 18:23:255008 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165009 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255010 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5011
bnc691fda62016-08-12 00:43:165012 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525013 ASSERT_TRUE(response);
5014 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025015 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165016
5017 std::string response_data;
bnc691fda62016-08-12 00:43:165018 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235019 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165020}
5021
5022// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015023TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275024 HttpRequestInfo request;
5025 request.method = "GET";
bncce36dca22015-04-21 22:11:235026 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275027
[email protected]d9da5fe2010-10-13 22:37:165028 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035029 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515030 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075031 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165033
bnc691fda62016-08-12 00:43:165034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165035
bncce36dca22015-04-21 22:11:235036 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415037 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235038 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415039 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085040 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165041
5042 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415043 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165044 };
5045
bnc42331402016-07-25 13:36:155046 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415047 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165048 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415049 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165050 };
5051
rch8e6c6c42015-05-01 14:05:135052 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5053 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075054 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165055
[email protected]8ddf8322012-02-23 18:08:065056 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365057 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065059 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365060 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165062
[email protected]49639fa2011-12-20 23:22:415063 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165064
bnc691fda62016-08-12 00:43:165065 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165067
5068 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015069 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165070
ttuttle960fcbf2016-04-19 13:26:325071 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165072}
5073
[email protected]f6c63db52013-02-02 00:35:225074// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5075// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015076TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225077 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5078 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035079 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515080 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075081 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095082 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505083 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225084
5085 HttpRequestInfo request1;
5086 request1.method = "GET";
bncce36dca22015-04-21 22:11:235087 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225088 request1.load_flags = 0;
5089
5090 HttpRequestInfo request2;
5091 request2.method = "GET";
bncce36dca22015-04-21 22:11:235092 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225093 request2.load_flags = 0;
5094
bncce36dca22015-04-21 22:11:235095 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415096 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235097 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155098 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225099
bncce36dca22015-04-21 22:11:235100 // Fetch https://www.example.org/ via HTTP.
5101 const char get1[] =
5102 "GET / HTTP/1.1\r\n"
5103 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225104 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415105 SpdySerializedFrame wrapped_get1(
5106 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225107 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5108 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415109 SpdySerializedFrame wrapped_get_resp1(
5110 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5111 SpdySerializedFrame wrapped_body1(
5112 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5113 SpdySerializedFrame window_update(
5114 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225115
bncce36dca22015-04-21 22:11:235116 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295117 SpdyHeaderBlock connect2_block;
5118 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405119 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155120 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5121 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395122
bnc42331402016-07-25 13:36:155123 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225124
bncce36dca22015-04-21 22:11:235125 // Fetch https://mail.example.org/ via HTTP.
5126 const char get2[] =
5127 "GET / HTTP/1.1\r\n"
5128 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225129 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415130 SpdySerializedFrame wrapped_get2(
5131 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225132 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5133 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415134 SpdySerializedFrame wrapped_get_resp2(
5135 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5136 SpdySerializedFrame wrapped_body2(
5137 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225138
5139 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415140 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5141 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225142 };
5143
5144 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415145 CreateMockRead(conn_resp1, 1, ASYNC),
5146 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5147 CreateMockRead(wrapped_body1, 4, ASYNC),
5148 CreateMockRead(conn_resp2, 6, ASYNC),
5149 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5150 CreateMockRead(wrapped_body2, 9, ASYNC),
5151 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225152 };
5153
mmenke11eb5152015-06-09 14:50:505154 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5155 arraysize(spdy_writes));
5156 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225157
5158 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365159 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225161 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505162 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225163 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225165
5166 TestCompletionCallback callback;
5167
bnc691fda62016-08-12 00:43:165168 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205169 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015170 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225171
5172 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165173 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225174 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5175
bnc691fda62016-08-12 00:43:165176 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525177 ASSERT_TRUE(response);
5178 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225179 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5180
5181 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295182 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165183 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505184 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225185
bnc691fda62016-08-12 00:43:165186 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205187 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015188 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225189
5190 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165191 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225192 // Even though the SPDY connection is reused, a new tunnelled connection has
5193 // to be created, so the socket's load timing looks like a fresh connection.
5194 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5195
5196 // The requests should have different IDs, since they each are using their own
5197 // separate stream.
5198 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5199
bnc691fda62016-08-12 00:43:165200 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505201 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225202}
5203
5204// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5205// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015206TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225207 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5208 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035209 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515210 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075211 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095212 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505213 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225214
5215 HttpRequestInfo request1;
5216 request1.method = "GET";
bncce36dca22015-04-21 22:11:235217 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225218 request1.load_flags = 0;
5219
5220 HttpRequestInfo request2;
5221 request2.method = "GET";
bncce36dca22015-04-21 22:11:235222 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225223 request2.load_flags = 0;
5224
bncce36dca22015-04-21 22:11:235225 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415226 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235227 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155228 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225229
bncce36dca22015-04-21 22:11:235230 // Fetch https://www.example.org/ via HTTP.
5231 const char get1[] =
5232 "GET / HTTP/1.1\r\n"
5233 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225234 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415235 SpdySerializedFrame wrapped_get1(
5236 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225237 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5238 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415239 SpdySerializedFrame wrapped_get_resp1(
5240 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5241 SpdySerializedFrame wrapped_body1(
5242 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5243 SpdySerializedFrame window_update(
5244 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225245
bncce36dca22015-04-21 22:11:235246 // Fetch https://www.example.org/2 via HTTP.
5247 const char get2[] =
5248 "GET /2 HTTP/1.1\r\n"
5249 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225250 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415251 SpdySerializedFrame wrapped_get2(
5252 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225253 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5254 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415255 SpdySerializedFrame wrapped_get_resp2(
5256 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5257 SpdySerializedFrame wrapped_body2(
5258 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225259
5260 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415261 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5262 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225263 };
5264
5265 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415266 CreateMockRead(conn_resp1, 1, ASYNC),
5267 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465268 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415269 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465270 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415271 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225272 };
5273
mmenke11eb5152015-06-09 14:50:505274 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5275 arraysize(spdy_writes));
5276 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225277
5278 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365279 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505280 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225281 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225283
5284 TestCompletionCallback callback;
5285
bnc87dcefc2017-05-25 12:47:585286 auto trans =
5287 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205288 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225290
5291 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015292 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225293
5294 LoadTimingInfo load_timing_info;
5295 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5296 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5297
5298 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525299 ASSERT_TRUE(response);
5300 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225301 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5302
5303 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295304 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505305 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225306 trans.reset();
5307
bnc87dcefc2017-05-25 12:47:585308 auto trans2 =
5309 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205310 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225312
[email protected]f6c63db52013-02-02 00:35:225313 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015314 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225315
5316 LoadTimingInfo load_timing_info2;
5317 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5318 TestLoadTimingReused(load_timing_info2);
5319
5320 // The requests should have the same ID.
5321 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5322
[email protected]90499482013-06-01 00:39:505323 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225324}
5325
5326// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5327// Proxy to different servers.
bncd16676a2016-07-20 16:23:015328TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225329 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035330 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515331 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075332 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095333 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505334 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225335
5336 HttpRequestInfo request1;
5337 request1.method = "GET";
bncce36dca22015-04-21 22:11:235338 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225339 request1.load_flags = 0;
5340
5341 HttpRequestInfo request2;
5342 request2.method = "GET";
bncce36dca22015-04-21 22:11:235343 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225344 request2.load_flags = 0;
5345
bncce36dca22015-04-21 22:11:235346 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265347 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235348 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415349 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155350 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5351 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415352 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385353 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225354
bncce36dca22015-04-21 22:11:235355 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265356 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235357 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415358 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155359 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5360 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415361 SpdySerializedFrame body2(
5362 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225363
5364 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415365 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225366 };
5367
5368 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415369 CreateMockRead(get_resp1, 1, ASYNC),
5370 CreateMockRead(body1, 2, ASYNC),
5371 CreateMockRead(get_resp2, 4, ASYNC),
5372 CreateMockRead(body2, 5, ASYNC),
5373 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225374 };
5375
mmenke11eb5152015-06-09 14:50:505376 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5377 arraysize(spdy_writes));
5378 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225379
5380 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365381 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225383
5384 TestCompletionCallback callback;
5385
bnc87dcefc2017-05-25 12:47:585386 auto trans =
5387 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205388 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015389 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225390
5391 LoadTimingInfo load_timing_info;
5392 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5393 TestLoadTimingNotReused(load_timing_info,
5394 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5395
5396 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525397 ASSERT_TRUE(response);
5398 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025399 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225400
5401 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295402 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505403 rv = trans->Read(buf.get(), 256, callback.callback());
5404 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225405 // Delete the first request, so the second one can reuse the socket.
5406 trans.reset();
5407
bnc691fda62016-08-12 00:43:165408 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205409 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015410 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225411
5412 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165413 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225414 TestLoadTimingReused(load_timing_info2);
5415
5416 // The requests should have the same ID.
5417 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5418
bnc691fda62016-08-12 00:43:165419 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505420 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225421}
5422
[email protected]2df19bb2010-08-25 20:13:465423// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015424TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465425 HttpRequestInfo request;
5426 request.method = "GET";
bncce36dca22015-04-21 22:11:235427 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465428 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295429 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465430
[email protected]79cb5c12011-09-12 13:12:045431 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035432 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515433 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075434 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275436
[email protected]2df19bb2010-08-25 20:13:465437 // Since we have proxy, should use full url
5438 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165439 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5440 "Host: www.example.org\r\n"
5441 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465442
bnc691fda62016-08-12 00:43:165443 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235444 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165445 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5446 "Host: www.example.org\r\n"
5447 "Proxy-Connection: keep-alive\r\n"
5448 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465449 };
5450
5451 // The proxy responds to the GET with a 407, using a persistent
5452 // connection.
5453 MockRead data_reads1[] = {
5454 // No credentials.
5455 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5456 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5457 MockRead("Proxy-Connection: keep-alive\r\n"),
5458 MockRead("Content-Length: 0\r\n\r\n"),
5459
5460 MockRead("HTTP/1.1 200 OK\r\n"),
5461 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5462 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065463 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465464 };
5465
5466 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5467 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075468 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065469 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075470 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465471
[email protected]49639fa2011-12-20 23:22:415472 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465473
bnc691fda62016-08-12 00:43:165474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505475
bnc691fda62016-08-12 00:43:165476 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465478
5479 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015480 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465481
[email protected]58e32bb2013-01-21 18:23:255482 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165483 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255484 TestLoadTimingNotReused(load_timing_info,
5485 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5486
bnc691fda62016-08-12 00:43:165487 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525488 ASSERT_TRUE(response);
5489 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465490 EXPECT_EQ(407, response->headers->response_code());
5491 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435492 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465493
[email protected]49639fa2011-12-20 23:22:415494 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465495
bnc691fda62016-08-12 00:43:165496 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465498
5499 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015500 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465501
[email protected]58e32bb2013-01-21 18:23:255502 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165503 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255504 // Retrying with HTTP AUTH is considered to be reusing a socket.
5505 TestLoadTimingReused(load_timing_info);
5506
bnc691fda62016-08-12 00:43:165507 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525508 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465509
5510 EXPECT_TRUE(response->headers->IsKeepAlive());
5511 EXPECT_EQ(200, response->headers->response_code());
5512 EXPECT_EQ(100, response->headers->GetContentLength());
5513 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5514
5515 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525516 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465517}
5518
[email protected]23e482282013-06-14 16:08:025519void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085520 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425521 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085522 request.method = "GET";
bncce36dca22015-04-21 22:11:235523 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085524
[email protected]cb9bf6ca2011-01-28 13:15:275525 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035526 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095527 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275528
[email protected]c744cf22009-02-27 07:28:085529 // Since we have proxy, should try to establish tunnel.
5530 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175531 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5532 "Host: www.example.org:443\r\n"
5533 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085534 };
5535
5536 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235537 status, MockRead("Content-Length: 10\r\n\r\n"),
5538 // No response body because the test stops reading here.
5539 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085540 };
5541
[email protected]31a2bfe2010-02-09 08:03:395542 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5543 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075544 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085545
[email protected]49639fa2011-12-20 23:22:415546 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085547
bnc691fda62016-08-12 00:43:165548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505549
tfarina42834112016-09-22 13:38:205550 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015551 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085552
5553 rv = callback.WaitForResult();
5554 EXPECT_EQ(expected_status, rv);
5555}
5556
[email protected]23e482282013-06-14 16:08:025557void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235558 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085559 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425560 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085561}
5562
bncd16676a2016-07-20 16:23:015563TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085564 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5565}
5566
bncd16676a2016-07-20 16:23:015567TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085568 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5569}
5570
bncd16676a2016-07-20 16:23:015571TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085572 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5573}
5574
bncd16676a2016-07-20 16:23:015575TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085576 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5577}
5578
bncd16676a2016-07-20 16:23:015579TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085580 ConnectStatusHelper(
5581 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5582}
5583
bncd16676a2016-07-20 16:23:015584TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085585 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5586}
5587
bncd16676a2016-07-20 16:23:015588TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085589 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5590}
5591
bncd16676a2016-07-20 16:23:015592TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085593 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5594}
5595
bncd16676a2016-07-20 16:23:015596TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085597 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5598}
5599
bncd16676a2016-07-20 16:23:015600TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085601 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5602}
5603
bncd16676a2016-07-20 16:23:015604TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085605 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5606}
5607
bncd16676a2016-07-20 16:23:015608TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085609 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5610}
5611
bncd16676a2016-07-20 16:23:015612TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085613 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5614}
5615
bncd16676a2016-07-20 16:23:015616TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085617 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5618}
5619
bncd16676a2016-07-20 16:23:015620TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085621 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5622}
5623
bncd16676a2016-07-20 16:23:015624TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085625 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5626}
5627
bncd16676a2016-07-20 16:23:015628TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375629 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5630}
5631
bncd16676a2016-07-20 16:23:015632TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085633 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5634}
5635
bncd16676a2016-07-20 16:23:015636TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085637 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5638}
5639
bncd16676a2016-07-20 16:23:015640TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085641 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5642}
5643
bncd16676a2016-07-20 16:23:015644TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085645 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5646}
5647
bncd16676a2016-07-20 16:23:015648TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085649 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5650}
5651
bncd16676a2016-07-20 16:23:015652TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085653 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5654}
5655
bncd16676a2016-07-20 16:23:015656TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085657 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5658}
5659
bncd16676a2016-07-20 16:23:015660TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085661 ConnectStatusHelperWithExpectedStatus(
5662 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545663 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085664}
5665
bncd16676a2016-07-20 16:23:015666TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085667 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5668}
5669
bncd16676a2016-07-20 16:23:015670TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085671 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5672}
5673
bncd16676a2016-07-20 16:23:015674TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085675 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5676}
5677
bncd16676a2016-07-20 16:23:015678TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085679 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5680}
5681
bncd16676a2016-07-20 16:23:015682TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085683 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5684}
5685
bncd16676a2016-07-20 16:23:015686TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085687 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5688}
5689
bncd16676a2016-07-20 16:23:015690TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085691 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5692}
5693
bncd16676a2016-07-20 16:23:015694TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085695 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5696}
5697
bncd16676a2016-07-20 16:23:015698TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085699 ConnectStatusHelper(
5700 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5701}
5702
bncd16676a2016-07-20 16:23:015703TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085704 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5705}
5706
bncd16676a2016-07-20 16:23:015707TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085708 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5709}
5710
bncd16676a2016-07-20 16:23:015711TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085712 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5713}
5714
bncd16676a2016-07-20 16:23:015715TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085716 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5717}
5718
bncd16676a2016-07-20 16:23:015719TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085720 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5721}
5722
bncd16676a2016-07-20 16:23:015723TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085724 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5725}
5726
bncd16676a2016-07-20 16:23:015727TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085728 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5729}
5730
[email protected]038e9a32008-10-08 22:40:165731// Test the flow when both the proxy server AND origin server require
5732// authentication. Again, this uses basic auth for both since that is
5733// the simplest to mock.
bncd16676a2016-07-20 16:23:015734TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275735 HttpRequestInfo request;
5736 request.method = "GET";
bncce36dca22015-04-21 22:11:235737 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275738
[email protected]038e9a32008-10-08 22:40:165739 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035740 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075742
bnc691fda62016-08-12 00:43:165743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165744
[email protected]f9ee6b52008-11-08 06:46:235745 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235746 MockWrite(
5747 "GET http://www.example.org/ HTTP/1.1\r\n"
5748 "Host: www.example.org\r\n"
5749 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235750 };
5751
[email protected]038e9a32008-10-08 22:40:165752 MockRead data_reads1[] = {
5753 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5754 // Give a couple authenticate options (only the middle one is actually
5755 // supported).
[email protected]22927ad2009-09-21 19:56:195756 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165757 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5758 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5759 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5760 // Large content-length -- won't matter, as connection will be reset.
5761 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065762 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165763 };
5764
bnc691fda62016-08-12 00:43:165765 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165766 // request we should be issuing -- the final header line contains the
5767 // proxy's credentials.
5768 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235769 MockWrite(
5770 "GET http://www.example.org/ HTTP/1.1\r\n"
5771 "Host: www.example.org\r\n"
5772 "Proxy-Connection: keep-alive\r\n"
5773 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165774 };
5775
5776 // Now the proxy server lets the request pass through to origin server.
5777 // The origin server responds with a 401.
5778 MockRead data_reads2[] = {
5779 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5780 // Note: We are using the same realm-name as the proxy server. This is
5781 // completely valid, as realms are unique across hosts.
5782 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5783 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5784 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065785 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165786 };
5787
bnc691fda62016-08-12 00:43:165788 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165789 // the credentials for both the proxy and origin server.
5790 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235791 MockWrite(
5792 "GET http://www.example.org/ HTTP/1.1\r\n"
5793 "Host: www.example.org\r\n"
5794 "Proxy-Connection: keep-alive\r\n"
5795 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5796 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165797 };
5798
5799 // Lastly we get the desired content.
5800 MockRead data_reads3[] = {
5801 MockRead("HTTP/1.0 200 OK\r\n"),
5802 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5803 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065804 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165805 };
5806
[email protected]31a2bfe2010-02-09 08:03:395807 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5808 data_writes1, arraysize(data_writes1));
5809 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5810 data_writes2, arraysize(data_writes2));
5811 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5812 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5814 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5815 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165816
[email protected]49639fa2011-12-20 23:22:415817 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165818
tfarina42834112016-09-22 13:38:205819 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165821
5822 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015823 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165824
bnc691fda62016-08-12 00:43:165825 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525826 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045827 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165828
[email protected]49639fa2011-12-20 23:22:415829 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165830
bnc691fda62016-08-12 00:43:165831 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165833
5834 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015835 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165836
bnc691fda62016-08-12 00:43:165837 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525838 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045839 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165840
[email protected]49639fa2011-12-20 23:22:415841 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165842
bnc691fda62016-08-12 00:43:165843 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5844 callback3.callback());
robpercival214763f2016-07-01 23:27:015845 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165846
5847 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015848 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165849
bnc691fda62016-08-12 00:43:165850 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525851 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165852 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165853}
[email protected]4ddaf2502008-10-23 18:26:195854
[email protected]ea9dc9a2009-09-05 00:43:325855// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5856// can't hook into its internals to cause it to generate predictable NTLM
5857// authorization headers.
5858#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295859// The NTLM authentication unit tests were generated by capturing the HTTP
5860// requests and responses using Fiddler 2 and inspecting the generated random
5861// bytes in the debugger.
5862
5863// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015864TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425865 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245866 request.method = "GET";
5867 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545868
5869 // Ensure load is not disrupted by flags which suppress behaviour specific
5870 // to other auth schemes.
5871 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245872
[email protected]cb9bf6ca2011-01-28 13:15:275873 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5874 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275876
[email protected]3f918782009-02-28 01:29:245877 MockWrite data_writes1[] = {
5878 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5879 "Host: 172.22.68.17\r\n"
5880 "Connection: keep-alive\r\n\r\n"),
5881 };
5882
5883 MockRead data_reads1[] = {
5884 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045885 // Negotiate and NTLM are often requested together. However, we only want
5886 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5887 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245888 MockRead("WWW-Authenticate: NTLM\r\n"),
5889 MockRead("Connection: close\r\n"),
5890 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365891 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245892 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065893 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245894 };
5895
5896 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165897 // After restarting with a null identity, this is the
5898 // request we should be issuing -- the final header line contains a Type
5899 // 1 message.
5900 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5901 "Host: 172.22.68.17\r\n"
5902 "Connection: keep-alive\r\n"
5903 "Authorization: NTLM "
5904 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245905
bnc691fda62016-08-12 00:43:165906 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5907 // (the credentials for the origin server). The second request continues
5908 // on the same connection.
5909 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5910 "Host: 172.22.68.17\r\n"
5911 "Connection: keep-alive\r\n"
5912 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5913 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5914 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5915 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5916 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245917 };
5918
5919 MockRead data_reads2[] = {
5920 // The origin server responds with a Type 2 message.
5921 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5922 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295923 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245924 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5925 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5926 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5927 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5928 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5929 "BtAAAAAAA=\r\n"),
5930 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365931 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245932 MockRead("You are not authorized to view this page\r\n"),
5933
5934 // Lastly we get the desired content.
5935 MockRead("HTTP/1.1 200 OK\r\n"),
5936 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5937 MockRead("Content-Length: 13\r\n\r\n"),
5938 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065939 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245940 };
5941
[email protected]31a2bfe2010-02-09 08:03:395942 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5943 data_writes1, arraysize(data_writes1));
5944 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5945 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075946 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5947 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245948
[email protected]49639fa2011-12-20 23:22:415949 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245950
bnc691fda62016-08-12 00:43:165951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505952
tfarina42834112016-09-22 13:38:205953 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245955
5956 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015957 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245958
bnc691fda62016-08-12 00:43:165959 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225960
bnc691fda62016-08-12 00:43:165961 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525962 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045963 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245964
[email protected]49639fa2011-12-20 23:22:415965 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255966
bnc691fda62016-08-12 00:43:165967 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5968 callback2.callback());
robpercival214763f2016-07-01 23:27:015969 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255970
5971 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015972 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255973
bnc691fda62016-08-12 00:43:165974 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255975
bnc691fda62016-08-12 00:43:165976 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525977 ASSERT_TRUE(response);
5978 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255979
[email protected]49639fa2011-12-20 23:22:415980 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245981
bnc691fda62016-08-12 00:43:165982 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245984
[email protected]0757e7702009-03-27 04:00:225985 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015986 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245987
bnc691fda62016-08-12 00:43:165988 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525989 ASSERT_TRUE(response);
5990 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245991 EXPECT_EQ(13, response->headers->GetContentLength());
5992}
5993
[email protected]385a4672009-03-11 22:21:295994// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015995TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425996 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295997 request.method = "GET";
5998 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:295999
[email protected]cb9bf6ca2011-01-28 13:15:276000 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
6001 MockGetHostName);
danakj1fd259a02016-04-16 03:17:096002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276003
[email protected]385a4672009-03-11 22:21:296004 MockWrite data_writes1[] = {
6005 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6006 "Host: 172.22.68.17\r\n"
6007 "Connection: keep-alive\r\n\r\n"),
6008 };
6009
6010 MockRead data_reads1[] = {
6011 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046012 // Negotiate and NTLM are often requested together. However, we only want
6013 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6014 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296015 MockRead("WWW-Authenticate: NTLM\r\n"),
6016 MockRead("Connection: close\r\n"),
6017 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366018 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296019 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066020 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296021 };
6022
6023 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166024 // After restarting with a null identity, this is the
6025 // request we should be issuing -- the final header line contains a Type
6026 // 1 message.
6027 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6028 "Host: 172.22.68.17\r\n"
6029 "Connection: keep-alive\r\n"
6030 "Authorization: NTLM "
6031 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296032
bnc691fda62016-08-12 00:43:166033 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6034 // (the credentials for the origin server). The second request continues
6035 // on the same connection.
6036 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6037 "Host: 172.22.68.17\r\n"
6038 "Connection: keep-alive\r\n"
6039 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6040 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6041 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6042 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6043 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296044 };
6045
6046 MockRead data_reads2[] = {
6047 // The origin server responds with a Type 2 message.
6048 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6049 MockRead("WWW-Authenticate: NTLM "
6050 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6051 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6052 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6053 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6054 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6055 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6056 "BtAAAAAAA=\r\n"),
6057 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366058 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296059 MockRead("You are not authorized to view this page\r\n"),
6060
6061 // Wrong password.
6062 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296063 MockRead("WWW-Authenticate: NTLM\r\n"),
6064 MockRead("Connection: close\r\n"),
6065 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366066 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296067 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066068 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296069 };
6070
6071 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166072 // After restarting with a null identity, this is the
6073 // request we should be issuing -- the final header line contains a Type
6074 // 1 message.
6075 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6076 "Host: 172.22.68.17\r\n"
6077 "Connection: keep-alive\r\n"
6078 "Authorization: NTLM "
6079 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296080
bnc691fda62016-08-12 00:43:166081 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6082 // (the credentials for the origin server). The second request continues
6083 // on the same connection.
6084 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6085 "Host: 172.22.68.17\r\n"
6086 "Connection: keep-alive\r\n"
6087 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6088 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6089 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6090 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6091 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296092 };
6093
6094 MockRead data_reads3[] = {
6095 // The origin server responds with a Type 2 message.
6096 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6097 MockRead("WWW-Authenticate: NTLM "
6098 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6099 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6100 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6101 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6102 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6103 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6104 "BtAAAAAAA=\r\n"),
6105 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366106 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296107 MockRead("You are not authorized to view this page\r\n"),
6108
6109 // Lastly we get the desired content.
6110 MockRead("HTTP/1.1 200 OK\r\n"),
6111 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6112 MockRead("Content-Length: 13\r\n\r\n"),
6113 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066114 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296115 };
6116
[email protected]31a2bfe2010-02-09 08:03:396117 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6118 data_writes1, arraysize(data_writes1));
6119 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6120 data_writes2, arraysize(data_writes2));
6121 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6122 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076123 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6124 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6125 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296126
[email protected]49639fa2011-12-20 23:22:416127 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296128
bnc691fda62016-08-12 00:43:166129 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506130
tfarina42834112016-09-22 13:38:206131 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296133
6134 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016135 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296136
bnc691fda62016-08-12 00:43:166137 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296138
bnc691fda62016-08-12 00:43:166139 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526140 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046141 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296142
[email protected]49639fa2011-12-20 23:22:416143 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296144
[email protected]0757e7702009-03-27 04:00:226145 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166146 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6147 callback2.callback());
robpercival214763f2016-07-01 23:27:016148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296149
[email protected]10af5fe72011-01-31 16:17:256150 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016151 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296152
bnc691fda62016-08-12 00:43:166153 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416154 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166155 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256157 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016158 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166159 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226160
bnc691fda62016-08-12 00:43:166161 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526162 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046163 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226164
[email protected]49639fa2011-12-20 23:22:416165 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226166
6167 // Now enter the right password.
bnc691fda62016-08-12 00:43:166168 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6169 callback4.callback());
robpercival214763f2016-07-01 23:27:016170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256171
6172 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016173 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256174
bnc691fda62016-08-12 00:43:166175 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256176
[email protected]49639fa2011-12-20 23:22:416177 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256178
6179 // One more roundtrip
bnc691fda62016-08-12 00:43:166180 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226182
6183 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016184 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226185
bnc691fda62016-08-12 00:43:166186 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526187 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296188 EXPECT_EQ(13, response->headers->GetContentLength());
6189}
[email protected]ea9dc9a2009-09-05 00:43:326190#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296191
[email protected]4ddaf2502008-10-23 18:26:196192// Test reading a server response which has only headers, and no body.
6193// After some maximum number of bytes is consumed, the transaction should
6194// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016195TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426196 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196197 request.method = "GET";
bncce36dca22015-04-21 22:11:236198 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196199
danakj1fd259a02016-04-16 03:17:096200 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276202
[email protected]b75b7b2f2009-10-06 00:54:536203 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436204 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536205 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196206
6207 MockRead data_reads[] = {
6208 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066209 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196210 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066211 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196212 };
[email protected]31a2bfe2010-02-09 08:03:396213 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076214 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196215
[email protected]49639fa2011-12-20 23:22:416216 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196217
tfarina42834112016-09-22 13:38:206218 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196220
6221 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016222 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196223}
[email protected]f4e426b2008-11-05 00:24:496224
6225// Make sure that we don't try to reuse a TCPClientSocket when failing to
6226// establish tunnel.
6227// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016228TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276229 HttpRequestInfo request;
6230 request.method = "GET";
bncce36dca22015-04-21 22:11:236231 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276232
[email protected]f4e426b2008-11-05 00:24:496233 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036234 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016235
danakj1fd259a02016-04-16 03:17:096236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496237
bnc87dcefc2017-05-25 12:47:586238 auto trans =
6239 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496240
[email protected]f4e426b2008-11-05 00:24:496241 // Since we have proxy, should try to establish tunnel.
6242 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176243 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6244 "Host: www.example.org:443\r\n"
6245 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496246 };
6247
[email protected]77848d12008-11-14 00:00:226248 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496249 // connection. Usually a proxy would return 501 (not implemented),
6250 // or 200 (tunnel established).
6251 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236252 MockRead("HTTP/1.1 404 Not Found\r\n"),
6253 MockRead("Content-Length: 10\r\n\r\n"),
6254 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496255 };
6256
[email protected]31a2bfe2010-02-09 08:03:396257 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6258 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076259 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496260
[email protected]49639fa2011-12-20 23:22:416261 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496262
tfarina42834112016-09-22 13:38:206263 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496265
6266 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016267 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496268
[email protected]b4404c02009-04-10 16:38:526269 // Empty the current queue. This is necessary because idle sockets are
6270 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556271 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526272
[email protected]f4e426b2008-11-05 00:24:496273 // We now check to make sure the TCPClientSocket was not added back to
6274 // the pool.
[email protected]90499482013-06-01 00:39:506275 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496276 trans.reset();
fdoray92e35a72016-06-10 15:54:556277 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496278 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506279 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496280}
[email protected]372d34a2008-11-05 21:30:516281
[email protected]1b157c02009-04-21 01:55:406282// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016283TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426284 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406285 request.method = "GET";
bncce36dca22015-04-21 22:11:236286 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406287
danakj1fd259a02016-04-16 03:17:096288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276289
bnc691fda62016-08-12 00:43:166290 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276291
[email protected]1b157c02009-04-21 01:55:406292 MockRead data_reads[] = {
6293 // A part of the response body is received with the response headers.
6294 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6295 // The rest of the response body is received in two parts.
6296 MockRead("lo"),
6297 MockRead(" world"),
6298 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066299 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406300 };
6301
[email protected]31a2bfe2010-02-09 08:03:396302 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076303 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406304
[email protected]49639fa2011-12-20 23:22:416305 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406306
tfarina42834112016-09-22 13:38:206307 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406309
6310 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016311 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406312
bnc691fda62016-08-12 00:43:166313 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526314 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406315
wezca1070932016-05-26 20:30:526316 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406317 std::string status_line = response->headers->GetStatusLine();
6318 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6319
[email protected]90499482013-06-01 00:39:506320 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406321
6322 std::string response_data;
bnc691fda62016-08-12 00:43:166323 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016324 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406325 EXPECT_EQ("hello world", response_data);
6326
6327 // Empty the current queue. This is necessary because idle sockets are
6328 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556329 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406330
6331 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506332 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406333}
6334
[email protected]76a505b2010-08-25 06:23:006335// Make sure that we recycle a SSL socket after reading all of the response
6336// body.
bncd16676a2016-07-20 16:23:016337TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006338 HttpRequestInfo request;
6339 request.method = "GET";
bncce36dca22015-04-21 22:11:236340 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006341
6342 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236343 MockWrite(
6344 "GET / HTTP/1.1\r\n"
6345 "Host: www.example.org\r\n"
6346 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006347 };
6348
6349 MockRead data_reads[] = {
6350 MockRead("HTTP/1.1 200 OK\r\n"),
6351 MockRead("Content-Length: 11\r\n\r\n"),
6352 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066353 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006354 };
6355
[email protected]8ddf8322012-02-23 18:08:066356 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006358
6359 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6360 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076361 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006362
[email protected]49639fa2011-12-20 23:22:416363 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006364
danakj1fd259a02016-04-16 03:17:096365 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006367
tfarina42834112016-09-22 13:38:206368 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006369
robpercival214763f2016-07-01 23:27:016370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6371 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006372
bnc691fda62016-08-12 00:43:166373 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526374 ASSERT_TRUE(response);
6375 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006376 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6377
[email protected]90499482013-06-01 00:39:506378 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006379
6380 std::string response_data;
bnc691fda62016-08-12 00:43:166381 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016382 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006383 EXPECT_EQ("hello world", response_data);
6384
6385 // Empty the current queue. This is necessary because idle sockets are
6386 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556387 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006388
6389 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506390 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006391}
6392
6393// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6394// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016395TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006396 HttpRequestInfo request;
6397 request.method = "GET";
bncce36dca22015-04-21 22:11:236398 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006399
6400 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236401 MockWrite(
6402 "GET / HTTP/1.1\r\n"
6403 "Host: www.example.org\r\n"
6404 "Connection: keep-alive\r\n\r\n"),
6405 MockWrite(
6406 "GET / HTTP/1.1\r\n"
6407 "Host: www.example.org\r\n"
6408 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006409 };
6410
6411 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426412 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6413 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006414
[email protected]8ddf8322012-02-23 18:08:066415 SSLSocketDataProvider ssl(ASYNC, OK);
6416 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076417 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006419
6420 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6421 data_writes, arraysize(data_writes));
6422 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6423 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076424 session_deps_.socket_factory->AddSocketDataProvider(&data);
6425 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006426
[email protected]49639fa2011-12-20 23:22:416427 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006428
danakj1fd259a02016-04-16 03:17:096429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586430 auto trans =
6431 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006432
tfarina42834112016-09-22 13:38:206433 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006434
robpercival214763f2016-07-01 23:27:016435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6436 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006437
6438 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526439 ASSERT_TRUE(response);
6440 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006441 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6442
[email protected]90499482013-06-01 00:39:506443 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006444
6445 std::string response_data;
6446 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016447 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006448 EXPECT_EQ("hello world", response_data);
6449
6450 // Empty the current queue. This is necessary because idle sockets are
6451 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556452 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006453
6454 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506455 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006456
6457 // Now start the second transaction, which should reuse the previous socket.
6458
bnc87dcefc2017-05-25 12:47:586459 trans =
6460 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006461
tfarina42834112016-09-22 13:38:206462 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006463
robpercival214763f2016-07-01 23:27:016464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6465 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006466
6467 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526468 ASSERT_TRUE(response);
6469 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006470 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6471
[email protected]90499482013-06-01 00:39:506472 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006473
6474 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016475 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006476 EXPECT_EQ("hello world", response_data);
6477
6478 // Empty the current queue. This is necessary because idle sockets are
6479 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556480 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006481
6482 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506483 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006484}
6485
maksim.sisov0adf8592016-07-15 06:25:566486// Grab a socket, use it, and put it back into the pool. Then, make
6487// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016488TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566489 HttpRequestInfo request;
6490 request.method = "GET";
6491 request.url = GURL("http://www.example.org/");
6492 request.load_flags = 0;
6493
6494 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6495
bnc691fda62016-08-12 00:43:166496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566497
6498 MockRead data_reads[] = {
6499 // A part of the response body is received with the response headers.
6500 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6501 // The rest of the response body is received in two parts.
6502 MockRead("lo"), MockRead(" world"),
6503 MockRead("junk"), // Should not be read!!
6504 MockRead(SYNCHRONOUS, OK),
6505 };
6506
6507 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6508 session_deps_.socket_factory->AddSocketDataProvider(&data);
6509
6510 TestCompletionCallback callback;
6511
tfarina42834112016-09-22 13:38:206512 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6514
6515 EXPECT_THAT(callback.GetResult(rv), IsOk());
6516
bnc691fda62016-08-12 00:43:166517 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566518 ASSERT_TRUE(response);
6519 EXPECT_TRUE(response->headers);
6520 std::string status_line = response->headers->GetStatusLine();
6521 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6522
6523 // Make memory critical notification and ensure the transaction still has been
6524 // operating right.
6525 base::MemoryPressureListener::NotifyMemoryPressure(
6526 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6527 base::RunLoop().RunUntilIdle();
6528
6529 // Socket should not be flushed as long as it is not idle.
6530 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6531
6532 std::string response_data;
bnc691fda62016-08-12 00:43:166533 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566534 EXPECT_THAT(rv, IsOk());
6535 EXPECT_EQ("hello world", response_data);
6536
6537 // Empty the current queue. This is necessary because idle sockets are
6538 // added to the connection pool asynchronously with a PostTask.
6539 base::RunLoop().RunUntilIdle();
6540
6541 // We now check to make sure the socket was added back to the pool.
6542 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6543
6544 // Idle sockets should be flushed now.
6545 base::MemoryPressureListener::NotifyMemoryPressure(
6546 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6547 base::RunLoop().RunUntilIdle();
6548
6549 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6550}
6551
6552// Grab an SSL socket, use it, and put it back into the pool. Then, make
6553// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016554TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566555 HttpRequestInfo request;
6556 request.method = "GET";
6557 request.url = GURL("https://www.example.org/");
6558 request.load_flags = 0;
6559
6560 MockWrite data_writes[] = {
6561 MockWrite("GET / HTTP/1.1\r\n"
6562 "Host: www.example.org\r\n"
6563 "Connection: keep-alive\r\n\r\n"),
6564 };
6565
6566 MockRead data_reads[] = {
6567 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6568 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6569
6570 SSLSocketDataProvider ssl(ASYNC, OK);
6571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6572
6573 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6574 arraysize(data_writes));
6575 session_deps_.socket_factory->AddSocketDataProvider(&data);
6576
6577 TestCompletionCallback callback;
6578
6579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566581
6582 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206583 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566584
6585 EXPECT_THAT(callback.GetResult(rv), IsOk());
6586
bnc691fda62016-08-12 00:43:166587 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566588 ASSERT_TRUE(response);
6589 ASSERT_TRUE(response->headers);
6590 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6591
6592 // Make memory critical notification and ensure the transaction still has been
6593 // operating right.
6594 base::MemoryPressureListener::NotifyMemoryPressure(
6595 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6596 base::RunLoop().RunUntilIdle();
6597
6598 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6599
6600 std::string response_data;
bnc691fda62016-08-12 00:43:166601 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566602 EXPECT_THAT(rv, IsOk());
6603 EXPECT_EQ("hello world", response_data);
6604
6605 // Empty the current queue. This is necessary because idle sockets are
6606 // added to the connection pool asynchronously with a PostTask.
6607 base::RunLoop().RunUntilIdle();
6608
6609 // We now check to make sure the socket was added back to the pool.
6610 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6611
6612 // Make memory notification once again and ensure idle socket is closed.
6613 base::MemoryPressureListener::NotifyMemoryPressure(
6614 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6615 base::RunLoop().RunUntilIdle();
6616
6617 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6618}
6619
[email protected]b4404c02009-04-10 16:38:526620// Make sure that we recycle a socket after a zero-length response.
6621// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016622TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426623 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526624 request.method = "GET";
bncce36dca22015-04-21 22:11:236625 request.url = GURL(
6626 "http://www.example.org/csi?v=3&s=web&action=&"
6627 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6628 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6629 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526630
danakj1fd259a02016-04-16 03:17:096631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276632
[email protected]b4404c02009-04-10 16:38:526633 MockRead data_reads[] = {
6634 MockRead("HTTP/1.1 204 No Content\r\n"
6635 "Content-Length: 0\r\n"
6636 "Content-Type: text/html\r\n\r\n"),
6637 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066638 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526639 };
6640
[email protected]31a2bfe2010-02-09 08:03:396641 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076642 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526643
mmenkecc2298e2015-12-07 18:20:186644 // Transaction must be created after the MockReads, so it's destroyed before
6645 // them.
bnc691fda62016-08-12 00:43:166646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186647
[email protected]49639fa2011-12-20 23:22:416648 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526649
tfarina42834112016-09-22 13:38:206650 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526652
6653 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016654 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526655
bnc691fda62016-08-12 00:43:166656 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526657 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526658
wezca1070932016-05-26 20:30:526659 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526660 std::string status_line = response->headers->GetStatusLine();
6661 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6662
[email protected]90499482013-06-01 00:39:506663 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526664
6665 std::string response_data;
bnc691fda62016-08-12 00:43:166666 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016667 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526668 EXPECT_EQ("", response_data);
6669
6670 // Empty the current queue. This is necessary because idle sockets are
6671 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556672 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526673
6674 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506675 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526676}
6677
bncd16676a2016-07-20 16:23:016678TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096679 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226680 element_readers.push_back(
ricea2deef682016-09-09 08:04:076681 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226682 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276683
[email protected]1c773ea12009-04-28 19:58:426684 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516685 // Transaction 1: a GET request that succeeds. The socket is recycled
6686 // after use.
6687 request[0].method = "GET";
6688 request[0].url = GURL("http://www.google.com/");
6689 request[0].load_flags = 0;
6690 // Transaction 2: a POST request. Reuses the socket kept alive from
6691 // transaction 1. The first attempts fails when writing the POST data.
6692 // This causes the transaction to retry with a new socket. The second
6693 // attempt succeeds.
6694 request[1].method = "POST";
6695 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276696 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516697 request[1].load_flags = 0;
6698
danakj1fd259a02016-04-16 03:17:096699 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516700
6701 // The first socket is used for transaction 1 and the first attempt of
6702 // transaction 2.
6703
6704 // The response of transaction 1.
6705 MockRead data_reads1[] = {
6706 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6707 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066708 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516709 };
6710 // The mock write results of transaction 1 and the first attempt of
6711 // transaction 2.
6712 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066713 MockWrite(SYNCHRONOUS, 64), // GET
6714 MockWrite(SYNCHRONOUS, 93), // POST
6715 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516716 };
[email protected]31a2bfe2010-02-09 08:03:396717 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6718 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516719
6720 // The second socket is used for the second attempt of transaction 2.
6721
6722 // The response of transaction 2.
6723 MockRead data_reads2[] = {
6724 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6725 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066726 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516727 };
6728 // The mock write results of the second attempt of transaction 2.
6729 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066730 MockWrite(SYNCHRONOUS, 93), // POST
6731 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516732 };
[email protected]31a2bfe2010-02-09 08:03:396733 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6734 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516735
[email protected]bb88e1d32013-05-03 23:11:076736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6737 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516738
thestig9d3bb0c2015-01-24 00:49:516739 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516740 "hello world", "welcome"
6741 };
6742
6743 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516745
[email protected]49639fa2011-12-20 23:22:416746 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516747
tfarina42834112016-09-22 13:38:206748 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516750
6751 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016752 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516753
bnc691fda62016-08-12 00:43:166754 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526755 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516756
wezca1070932016-05-26 20:30:526757 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516758 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6759
6760 std::string response_data;
bnc691fda62016-08-12 00:43:166761 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016762 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516763 EXPECT_EQ(kExpectedResponseData[i], response_data);
6764 }
6765}
[email protected]f9ee6b52008-11-08 06:46:236766
6767// Test the request-challenge-retry sequence for basic auth when there is
6768// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166769// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016770TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426771 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236772 request.method = "GET";
bncce36dca22015-04-21 22:11:236773 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416774 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296775
danakj1fd259a02016-04-16 03:17:096776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276778
[email protected]a97cca42009-08-14 01:00:296779 // The password contains an escaped character -- for this test to pass it
6780 // will need to be unescaped by HttpNetworkTransaction.
6781 EXPECT_EQ("b%40r", request.url.password());
6782
[email protected]f9ee6b52008-11-08 06:46:236783 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236784 MockWrite(
6785 "GET / HTTP/1.1\r\n"
6786 "Host: www.example.org\r\n"
6787 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236788 };
6789
6790 MockRead data_reads1[] = {
6791 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6792 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6793 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066794 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236795 };
6796
[email protected]2262e3a2012-05-22 16:08:166797 // After the challenge above, the transaction will be restarted using the
6798 // identity from the url (foo, b@r) to answer the challenge.
6799 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236800 MockWrite(
6801 "GET / HTTP/1.1\r\n"
6802 "Host: www.example.org\r\n"
6803 "Connection: keep-alive\r\n"
6804 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166805 };
6806
6807 MockRead data_reads2[] = {
6808 MockRead("HTTP/1.0 200 OK\r\n"),
6809 MockRead("Content-Length: 100\r\n\r\n"),
6810 MockRead(SYNCHRONOUS, OK),
6811 };
6812
[email protected]31a2bfe2010-02-09 08:03:396813 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6814 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166815 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6816 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076817 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6818 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236819
[email protected]49639fa2011-12-20 23:22:416820 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206821 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236823 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016824 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166825 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166826
6827 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166828 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166830 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016831 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166832 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226833
bnc691fda62016-08-12 00:43:166834 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526835 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166836
6837 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526838 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166839
6840 EXPECT_EQ(100, response->headers->GetContentLength());
6841
6842 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556843 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166844}
6845
6846// Test the request-challenge-retry sequence for basic auth when there is an
6847// incorrect identity in the URL. The identity from the URL should be used only
6848// once.
bncd16676a2016-07-20 16:23:016849TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166850 HttpRequestInfo request;
6851 request.method = "GET";
6852 // Note: the URL has a username:password in it. The password "baz" is
6853 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236854 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166855
6856 request.load_flags = LOAD_NORMAL;
6857
danakj1fd259a02016-04-16 03:17:096858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166860
6861 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236862 MockWrite(
6863 "GET / HTTP/1.1\r\n"
6864 "Host: www.example.org\r\n"
6865 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166866 };
6867
6868 MockRead data_reads1[] = {
6869 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6870 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6871 MockRead("Content-Length: 10\r\n\r\n"),
6872 MockRead(SYNCHRONOUS, ERR_FAILED),
6873 };
6874
6875 // After the challenge above, the transaction will be restarted using the
6876 // identity from the url (foo, baz) to answer the challenge.
6877 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236878 MockWrite(
6879 "GET / HTTP/1.1\r\n"
6880 "Host: www.example.org\r\n"
6881 "Connection: keep-alive\r\n"
6882 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166883 };
6884
6885 MockRead data_reads2[] = {
6886 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6887 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6888 MockRead("Content-Length: 10\r\n\r\n"),
6889 MockRead(SYNCHRONOUS, ERR_FAILED),
6890 };
6891
6892 // After the challenge above, the transaction will be restarted using the
6893 // identity supplied by the user (foo, bar) to answer the challenge.
6894 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236895 MockWrite(
6896 "GET / HTTP/1.1\r\n"
6897 "Host: www.example.org\r\n"
6898 "Connection: keep-alive\r\n"
6899 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166900 };
6901
6902 MockRead data_reads3[] = {
6903 MockRead("HTTP/1.0 200 OK\r\n"),
6904 MockRead("Content-Length: 100\r\n\r\n"),
6905 MockRead(SYNCHRONOUS, OK),
6906 };
6907
6908 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6909 data_writes1, arraysize(data_writes1));
6910 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6911 data_writes2, arraysize(data_writes2));
6912 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6913 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076914 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6915 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6916 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166917
6918 TestCompletionCallback callback1;
6919
tfarina42834112016-09-22 13:38:206920 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166922
6923 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016924 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166925
bnc691fda62016-08-12 00:43:166926 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166927 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166928 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166930 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016931 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166932 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166933
bnc691fda62016-08-12 00:43:166934 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526935 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166936 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6937
6938 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166939 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166941 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016942 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166943 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166944
bnc691fda62016-08-12 00:43:166945 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526946 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166947
6948 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526949 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166950
6951 EXPECT_EQ(100, response->headers->GetContentLength());
6952
[email protected]ea9dc9a2009-09-05 00:43:326953 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556954 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326955}
6956
[email protected]2217aa22013-10-11 03:03:546957
6958// Test the request-challenge-retry sequence for basic auth when there is a
6959// correct identity in the URL, but its use is being suppressed. The identity
6960// from the URL should never be used.
bncd16676a2016-07-20 16:23:016961TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546962 HttpRequestInfo request;
6963 request.method = "GET";
bncce36dca22015-04-21 22:11:236964 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546965 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6966
danakj1fd259a02016-04-16 03:17:096967 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166968 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546969
6970 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236971 MockWrite(
6972 "GET / HTTP/1.1\r\n"
6973 "Host: www.example.org\r\n"
6974 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546975 };
6976
6977 MockRead data_reads1[] = {
6978 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6979 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6980 MockRead("Content-Length: 10\r\n\r\n"),
6981 MockRead(SYNCHRONOUS, ERR_FAILED),
6982 };
6983
6984 // After the challenge above, the transaction will be restarted using the
6985 // identity supplied by the user, not the one in the URL, to answer the
6986 // challenge.
6987 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236988 MockWrite(
6989 "GET / HTTP/1.1\r\n"
6990 "Host: www.example.org\r\n"
6991 "Connection: keep-alive\r\n"
6992 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546993 };
6994
6995 MockRead data_reads3[] = {
6996 MockRead("HTTP/1.0 200 OK\r\n"),
6997 MockRead("Content-Length: 100\r\n\r\n"),
6998 MockRead(SYNCHRONOUS, OK),
6999 };
7000
7001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7002 data_writes1, arraysize(data_writes1));
7003 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7004 data_writes3, arraysize(data_writes3));
7005 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7006 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7007
7008 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207009 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547011 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017012 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167013 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547014
bnc691fda62016-08-12 00:43:167015 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527016 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547017 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7018
7019 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167020 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547022 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017023 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167024 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547025
bnc691fda62016-08-12 00:43:167026 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527027 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547028
7029 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527030 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547031 EXPECT_EQ(100, response->headers->GetContentLength());
7032
7033 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557034 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547035}
7036
[email protected]f9ee6b52008-11-08 06:46:237037// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017038TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237040
7041 // Transaction 1: authenticate (foo, bar) on MyRealm1
7042 {
[email protected]1c773ea12009-04-28 19:58:427043 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237044 request.method = "GET";
bncce36dca22015-04-21 22:11:237045 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237046
bnc691fda62016-08-12 00:43:167047 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277048
[email protected]f9ee6b52008-11-08 06:46:237049 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237050 MockWrite(
7051 "GET /x/y/z HTTP/1.1\r\n"
7052 "Host: www.example.org\r\n"
7053 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237054 };
7055
7056 MockRead data_reads1[] = {
7057 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7058 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7059 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067060 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237061 };
7062
7063 // Resend with authorization (username=foo, password=bar)
7064 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237065 MockWrite(
7066 "GET /x/y/z HTTP/1.1\r\n"
7067 "Host: www.example.org\r\n"
7068 "Connection: keep-alive\r\n"
7069 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237070 };
7071
7072 // Sever accepts the authorization.
7073 MockRead data_reads2[] = {
7074 MockRead("HTTP/1.0 200 OK\r\n"),
7075 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067076 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237077 };
7078
[email protected]31a2bfe2010-02-09 08:03:397079 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7080 data_writes1, arraysize(data_writes1));
7081 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7082 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077083 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7084 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237085
[email protected]49639fa2011-12-20 23:22:417086 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237087
tfarina42834112016-09-22 13:38:207088 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237090
7091 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017092 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237093
bnc691fda62016-08-12 00:43:167094 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527095 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047096 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237097
[email protected]49639fa2011-12-20 23:22:417098 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237099
bnc691fda62016-08-12 00:43:167100 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7101 callback2.callback());
robpercival214763f2016-07-01 23:27:017102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237103
7104 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017105 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237106
bnc691fda62016-08-12 00:43:167107 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527108 ASSERT_TRUE(response);
7109 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237110 EXPECT_EQ(100, response->headers->GetContentLength());
7111 }
7112
7113 // ------------------------------------------------------------------------
7114
7115 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7116 {
[email protected]1c773ea12009-04-28 19:58:427117 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237118 request.method = "GET";
7119 // Note that Transaction 1 was at /x/y/z, so this is in the same
7120 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237121 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237122
bnc691fda62016-08-12 00:43:167123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277124
[email protected]f9ee6b52008-11-08 06:46:237125 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237126 MockWrite(
7127 "GET /x/y/a/b HTTP/1.1\r\n"
7128 "Host: www.example.org\r\n"
7129 "Connection: keep-alive\r\n"
7130 // Send preemptive authorization for MyRealm1
7131 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237132 };
7133
7134 // The server didn't like the preemptive authorization, and
7135 // challenges us for a different realm (MyRealm2).
7136 MockRead data_reads1[] = {
7137 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7138 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7139 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067140 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237141 };
7142
7143 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7144 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237145 MockWrite(
7146 "GET /x/y/a/b HTTP/1.1\r\n"
7147 "Host: www.example.org\r\n"
7148 "Connection: keep-alive\r\n"
7149 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237150 };
7151
7152 // Sever accepts the authorization.
7153 MockRead data_reads2[] = {
7154 MockRead("HTTP/1.0 200 OK\r\n"),
7155 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067156 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237157 };
7158
[email protected]31a2bfe2010-02-09 08:03:397159 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7160 data_writes1, arraysize(data_writes1));
7161 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7162 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077163 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7164 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237165
[email protected]49639fa2011-12-20 23:22:417166 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237167
tfarina42834112016-09-22 13:38:207168 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017169 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237170
7171 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017172 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237173
bnc691fda62016-08-12 00:43:167174 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527175 ASSERT_TRUE(response);
7176 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047177 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437178 EXPECT_EQ("http://www.example.org",
7179 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047180 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197181 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237182
[email protected]49639fa2011-12-20 23:22:417183 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237184
bnc691fda62016-08-12 00:43:167185 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7186 callback2.callback());
robpercival214763f2016-07-01 23:27:017187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237188
7189 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017190 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237191
bnc691fda62016-08-12 00:43:167192 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527193 ASSERT_TRUE(response);
7194 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237195 EXPECT_EQ(100, response->headers->GetContentLength());
7196 }
7197
7198 // ------------------------------------------------------------------------
7199
7200 // Transaction 3: Resend a request in MyRealm's protection space --
7201 // succeed with preemptive authorization.
7202 {
[email protected]1c773ea12009-04-28 19:58:427203 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237204 request.method = "GET";
bncce36dca22015-04-21 22:11:237205 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237206
bnc691fda62016-08-12 00:43:167207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277208
[email protected]f9ee6b52008-11-08 06:46:237209 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237210 MockWrite(
7211 "GET /x/y/z2 HTTP/1.1\r\n"
7212 "Host: www.example.org\r\n"
7213 "Connection: keep-alive\r\n"
7214 // The authorization for MyRealm1 gets sent preemptively
7215 // (since the url is in the same protection space)
7216 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237217 };
7218
7219 // Sever accepts the preemptive authorization
7220 MockRead data_reads1[] = {
7221 MockRead("HTTP/1.0 200 OK\r\n"),
7222 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067223 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237224 };
7225
[email protected]31a2bfe2010-02-09 08:03:397226 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7227 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077228 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237229
[email protected]49639fa2011-12-20 23:22:417230 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237231
tfarina42834112016-09-22 13:38:207232 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237234
7235 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017236 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237237
bnc691fda62016-08-12 00:43:167238 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527239 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237240
wezca1070932016-05-26 20:30:527241 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237242 EXPECT_EQ(100, response->headers->GetContentLength());
7243 }
7244
7245 // ------------------------------------------------------------------------
7246
7247 // Transaction 4: request another URL in MyRealm (however the
7248 // url is not known to belong to the protection space, so no pre-auth).
7249 {
[email protected]1c773ea12009-04-28 19:58:427250 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237251 request.method = "GET";
bncce36dca22015-04-21 22:11:237252 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237253
bnc691fda62016-08-12 00:43:167254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277255
[email protected]f9ee6b52008-11-08 06:46:237256 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237257 MockWrite(
7258 "GET /x/1 HTTP/1.1\r\n"
7259 "Host: www.example.org\r\n"
7260 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237261 };
7262
7263 MockRead data_reads1[] = {
7264 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7265 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7266 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067267 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237268 };
7269
7270 // Resend with authorization from MyRealm's cache.
7271 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237272 MockWrite(
7273 "GET /x/1 HTTP/1.1\r\n"
7274 "Host: www.example.org\r\n"
7275 "Connection: keep-alive\r\n"
7276 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237277 };
7278
7279 // Sever accepts the authorization.
7280 MockRead data_reads2[] = {
7281 MockRead("HTTP/1.0 200 OK\r\n"),
7282 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067283 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237284 };
7285
[email protected]31a2bfe2010-02-09 08:03:397286 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7287 data_writes1, arraysize(data_writes1));
7288 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7289 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077290 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7291 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237292
[email protected]49639fa2011-12-20 23:22:417293 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237294
tfarina42834112016-09-22 13:38:207295 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237297
7298 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017299 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237300
bnc691fda62016-08-12 00:43:167301 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417302 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167303 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227305 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017306 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167307 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227308
bnc691fda62016-08-12 00:43:167309 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527310 ASSERT_TRUE(response);
7311 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237312 EXPECT_EQ(100, response->headers->GetContentLength());
7313 }
7314
7315 // ------------------------------------------------------------------------
7316
7317 // Transaction 5: request a URL in MyRealm, but the server rejects the
7318 // cached identity. Should invalidate and re-prompt.
7319 {
[email protected]1c773ea12009-04-28 19:58:427320 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237321 request.method = "GET";
bncce36dca22015-04-21 22:11:237322 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237323
bnc691fda62016-08-12 00:43:167324 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277325
[email protected]f9ee6b52008-11-08 06:46:237326 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237327 MockWrite(
7328 "GET /p/q/t HTTP/1.1\r\n"
7329 "Host: www.example.org\r\n"
7330 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237331 };
7332
7333 MockRead data_reads1[] = {
7334 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7335 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7336 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067337 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237338 };
7339
7340 // Resend with authorization from cache for MyRealm.
7341 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237342 MockWrite(
7343 "GET /p/q/t HTTP/1.1\r\n"
7344 "Host: www.example.org\r\n"
7345 "Connection: keep-alive\r\n"
7346 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237347 };
7348
7349 // Sever rejects the authorization.
7350 MockRead data_reads2[] = {
7351 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7352 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7353 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067354 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237355 };
7356
7357 // At this point we should prompt for new credentials for MyRealm.
7358 // Restart with username=foo3, password=foo4.
7359 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237360 MockWrite(
7361 "GET /p/q/t HTTP/1.1\r\n"
7362 "Host: www.example.org\r\n"
7363 "Connection: keep-alive\r\n"
7364 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237365 };
7366
7367 // Sever accepts the authorization.
7368 MockRead data_reads3[] = {
7369 MockRead("HTTP/1.0 200 OK\r\n"),
7370 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067371 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237372 };
7373
[email protected]31a2bfe2010-02-09 08:03:397374 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7375 data_writes1, arraysize(data_writes1));
7376 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7377 data_writes2, arraysize(data_writes2));
7378 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7379 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077380 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7381 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7382 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237383
[email protected]49639fa2011-12-20 23:22:417384 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237385
tfarina42834112016-09-22 13:38:207386 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017387 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237388
7389 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017390 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237391
bnc691fda62016-08-12 00:43:167392 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417393 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167394 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017395 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227396 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017397 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167398 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227399
bnc691fda62016-08-12 00:43:167400 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527401 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047402 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237403
[email protected]49639fa2011-12-20 23:22:417404 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237405
bnc691fda62016-08-12 00:43:167406 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7407 callback3.callback());
robpercival214763f2016-07-01 23:27:017408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237409
[email protected]0757e7702009-03-27 04:00:227410 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017411 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237412
bnc691fda62016-08-12 00:43:167413 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527414 ASSERT_TRUE(response);
7415 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237416 EXPECT_EQ(100, response->headers->GetContentLength());
7417 }
7418}
[email protected]89ceba9a2009-03-21 03:46:067419
[email protected]3c32c5f2010-05-18 15:18:127420// Tests that nonce count increments when multiple auth attempts
7421// are started with the same nonce.
bncd16676a2016-07-20 16:23:017422TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447423 HttpAuthHandlerDigest::Factory* digest_factory =
7424 new HttpAuthHandlerDigest::Factory();
7425 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7426 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7427 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077428 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127430
7431 // Transaction 1: authenticate (foo, bar) on MyRealm1
7432 {
[email protected]3c32c5f2010-05-18 15:18:127433 HttpRequestInfo request;
7434 request.method = "GET";
bncce36dca22015-04-21 22:11:237435 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127436
bnc691fda62016-08-12 00:43:167437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277438
[email protected]3c32c5f2010-05-18 15:18:127439 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237440 MockWrite(
7441 "GET /x/y/z HTTP/1.1\r\n"
7442 "Host: www.example.org\r\n"
7443 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127444 };
7445
7446 MockRead data_reads1[] = {
7447 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7448 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7449 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067450 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127451 };
7452
7453 // Resend with authorization (username=foo, password=bar)
7454 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237455 MockWrite(
7456 "GET /x/y/z HTTP/1.1\r\n"
7457 "Host: www.example.org\r\n"
7458 "Connection: keep-alive\r\n"
7459 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7460 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7461 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7462 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127463 };
7464
7465 // Sever accepts the authorization.
7466 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087467 MockRead("HTTP/1.0 200 OK\r\n"),
7468 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127469 };
7470
7471 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7472 data_writes1, arraysize(data_writes1));
7473 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7474 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077475 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7476 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127477
[email protected]49639fa2011-12-20 23:22:417478 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127479
tfarina42834112016-09-22 13:38:207480 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127482
7483 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017484 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127485
bnc691fda62016-08-12 00:43:167486 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527487 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047488 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127489
[email protected]49639fa2011-12-20 23:22:417490 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127491
bnc691fda62016-08-12 00:43:167492 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7493 callback2.callback());
robpercival214763f2016-07-01 23:27:017494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127495
7496 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017497 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127498
bnc691fda62016-08-12 00:43:167499 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527500 ASSERT_TRUE(response);
7501 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127502 }
7503
7504 // ------------------------------------------------------------------------
7505
7506 // Transaction 2: Request another resource in digestive's protection space.
7507 // This will preemptively add an Authorization header which should have an
7508 // "nc" value of 2 (as compared to 1 in the first use.
7509 {
[email protected]3c32c5f2010-05-18 15:18:127510 HttpRequestInfo request;
7511 request.method = "GET";
7512 // Note that Transaction 1 was at /x/y/z, so this is in the same
7513 // protection space as digest.
bncce36dca22015-04-21 22:11:237514 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127515
bnc691fda62016-08-12 00:43:167516 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277517
[email protected]3c32c5f2010-05-18 15:18:127518 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237519 MockWrite(
7520 "GET /x/y/a/b HTTP/1.1\r\n"
7521 "Host: www.example.org\r\n"
7522 "Connection: keep-alive\r\n"
7523 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7524 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7525 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7526 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127527 };
7528
7529 // Sever accepts the authorization.
7530 MockRead data_reads1[] = {
7531 MockRead("HTTP/1.0 200 OK\r\n"),
7532 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067533 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127534 };
7535
7536 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7537 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077538 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127539
[email protected]49639fa2011-12-20 23:22:417540 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127541
tfarina42834112016-09-22 13:38:207542 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127544
7545 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017546 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127547
bnc691fda62016-08-12 00:43:167548 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527549 ASSERT_TRUE(response);
7550 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127551 }
7552}
7553
[email protected]89ceba9a2009-03-21 03:46:067554// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017555TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067556 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067559
7560 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167561 trans.read_buf_ = new IOBuffer(15);
7562 trans.read_buf_len_ = 15;
7563 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067564
7565 // Setup state in response_
bnc691fda62016-08-12 00:43:167566 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577567 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087568 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577569 response->response_time = base::Time::Now();
7570 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067571
7572 { // Setup state for response_.vary_data
7573 HttpRequestInfo request;
7574 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7575 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277576 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437577 request.extra_headers.SetHeader("Foo", "1");
7578 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507579 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067580 }
7581
7582 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167583 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067584
7585 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167586 EXPECT_FALSE(trans.read_buf_);
7587 EXPECT_EQ(0, trans.read_buf_len_);
7588 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527589 EXPECT_FALSE(response->auth_challenge);
7590 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047591 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087592 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577593 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067594}
7595
[email protected]bacff652009-03-31 17:50:337596// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017597TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337598 HttpRequestInfo request;
7599 request.method = "GET";
bncce36dca22015-04-21 22:11:237600 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337601
danakj1fd259a02016-04-16 03:17:097602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277604
[email protected]bacff652009-03-31 17:50:337605 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237606 MockWrite(
7607 "GET / HTTP/1.1\r\n"
7608 "Host: www.example.org\r\n"
7609 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337610 };
7611
7612 MockRead data_reads[] = {
7613 MockRead("HTTP/1.0 200 OK\r\n"),
7614 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7615 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067616 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337617 };
7618
[email protected]5ecc992a42009-11-11 01:41:597619 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397620 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7621 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067622 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7623 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337624
[email protected]bb88e1d32013-05-03 23:11:077625 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7626 session_deps_.socket_factory->AddSocketDataProvider(&data);
7627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337629
[email protected]49639fa2011-12-20 23:22:417630 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337631
tfarina42834112016-09-22 13:38:207632 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337634
7635 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017636 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337637
bnc691fda62016-08-12 00:43:167638 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017639 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337640
7641 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017642 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337643
bnc691fda62016-08-12 00:43:167644 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337645
wezca1070932016-05-26 20:30:527646 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337647 EXPECT_EQ(100, response->headers->GetContentLength());
7648}
7649
7650// Test HTTPS connections to a site with a bad certificate, going through a
7651// proxy
bncd16676a2016-07-20 16:23:017652TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037653 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337654
7655 HttpRequestInfo request;
7656 request.method = "GET";
bncce36dca22015-04-21 22:11:237657 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337658
7659 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177660 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7661 "Host: www.example.org:443\r\n"
7662 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337663 };
7664
7665 MockRead proxy_reads[] = {
7666 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067667 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337668 };
7669
7670 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177671 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7672 "Host: www.example.org:443\r\n"
7673 "Proxy-Connection: keep-alive\r\n\r\n"),
7674 MockWrite("GET / HTTP/1.1\r\n"
7675 "Host: www.example.org\r\n"
7676 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337677 };
7678
7679 MockRead data_reads[] = {
7680 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7681 MockRead("HTTP/1.0 200 OK\r\n"),
7682 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7683 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067684 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337685 };
7686
[email protected]31a2bfe2010-02-09 08:03:397687 StaticSocketDataProvider ssl_bad_certificate(
7688 proxy_reads, arraysize(proxy_reads),
7689 proxy_writes, arraysize(proxy_writes));
7690 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7691 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067692 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7693 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337694
[email protected]bb88e1d32013-05-03 23:11:077695 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7696 session_deps_.socket_factory->AddSocketDataProvider(&data);
7697 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7698 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337699
[email protected]49639fa2011-12-20 23:22:417700 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337701
7702 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077703 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337704
danakj1fd259a02016-04-16 03:17:097705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337707
tfarina42834112016-09-22 13:38:207708 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337710
7711 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017712 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337713
bnc691fda62016-08-12 00:43:167714 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337716
7717 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017718 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337719
bnc691fda62016-08-12 00:43:167720 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337721
wezca1070932016-05-26 20:30:527722 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337723 EXPECT_EQ(100, response->headers->GetContentLength());
7724 }
7725}
7726
[email protected]2df19bb2010-08-25 20:13:467727
7728// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017729TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037730 session_deps_.proxy_service =
7731 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517732 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077733 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467734
7735 HttpRequestInfo request;
7736 request.method = "GET";
bncce36dca22015-04-21 22:11:237737 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467738
7739 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177740 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7741 "Host: www.example.org:443\r\n"
7742 "Proxy-Connection: keep-alive\r\n\r\n"),
7743 MockWrite("GET / HTTP/1.1\r\n"
7744 "Host: www.example.org\r\n"
7745 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467746 };
7747
7748 MockRead data_reads[] = {
7749 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7750 MockRead("HTTP/1.1 200 OK\r\n"),
7751 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7752 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067753 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467754 };
7755
7756 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7757 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067758 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7759 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467760
[email protected]bb88e1d32013-05-03 23:11:077761 session_deps_.socket_factory->AddSocketDataProvider(&data);
7762 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7763 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467764
[email protected]49639fa2011-12-20 23:22:417765 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467766
danakj1fd259a02016-04-16 03:17:097767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467769
tfarina42834112016-09-22 13:38:207770 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467772
7773 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017774 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167775 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467776
wezca1070932016-05-26 20:30:527777 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467778
tbansal2ecbbc72016-10-06 17:15:477779 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467780 EXPECT_TRUE(response->headers->IsKeepAlive());
7781 EXPECT_EQ(200, response->headers->response_code());
7782 EXPECT_EQ(100, response->headers->GetContentLength());
7783 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207784
7785 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167786 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207787 TestLoadTimingNotReusedWithPac(load_timing_info,
7788 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467789}
7790
[email protected]511f6f52010-12-17 03:58:297791// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017792TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037793 session_deps_.proxy_service =
7794 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517795 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077796 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297797
7798 HttpRequestInfo request;
7799 request.method = "GET";
bncce36dca22015-04-21 22:11:237800 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297801
7802 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177803 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7804 "Host: www.example.org:443\r\n"
7805 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297806 };
7807
7808 MockRead data_reads[] = {
7809 MockRead("HTTP/1.1 302 Redirect\r\n"),
7810 MockRead("Location: http://login.example.com/\r\n"),
7811 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067812 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297813 };
7814
7815 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7816 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067817 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297818
[email protected]bb88e1d32013-05-03 23:11:077819 session_deps_.socket_factory->AddSocketDataProvider(&data);
7820 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297821
[email protected]49639fa2011-12-20 23:22:417822 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297823
danakj1fd259a02016-04-16 03:17:097824 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167825 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297826
tfarina42834112016-09-22 13:38:207827 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297829
7830 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017831 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167832 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297833
wezca1070932016-05-26 20:30:527834 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297835
7836 EXPECT_EQ(302, response->headers->response_code());
7837 std::string url;
7838 EXPECT_TRUE(response->headers->IsRedirect(&url));
7839 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207840
7841 // In the case of redirects from proxies, HttpNetworkTransaction returns
7842 // timing for the proxy connection instead of the connection to the host,
7843 // and no send / receive times.
7844 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7845 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167846 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207847
7848 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197849 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207850
7851 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7852 EXPECT_LE(load_timing_info.proxy_resolve_start,
7853 load_timing_info.proxy_resolve_end);
7854 EXPECT_LE(load_timing_info.proxy_resolve_end,
7855 load_timing_info.connect_timing.connect_start);
7856 ExpectConnectTimingHasTimes(
7857 load_timing_info.connect_timing,
7858 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7859
7860 EXPECT_TRUE(load_timing_info.send_start.is_null());
7861 EXPECT_TRUE(load_timing_info.send_end.is_null());
7862 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297863}
7864
7865// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017866TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037867 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297868
7869 HttpRequestInfo request;
7870 request.method = "GET";
bncce36dca22015-04-21 22:11:237871 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297872
bncdf80d44fd2016-07-15 20:27:417873 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237874 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417875 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:087876 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297877 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417878 CreateMockWrite(conn, 0, SYNCHRONOUS),
7879 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297880 };
7881
7882 static const char* const kExtraHeaders[] = {
7883 "location",
7884 "http://login.example.com/",
7885 };
bnc42331402016-07-25 13:36:157886 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237887 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297888 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417889 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297890 };
7891
rch8e6c6c42015-05-01 14:05:137892 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7893 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067894 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367895 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297896
[email protected]bb88e1d32013-05-03 23:11:077897 session_deps_.socket_factory->AddSocketDataProvider(&data);
7898 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297899
[email protected]49639fa2011-12-20 23:22:417900 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297901
danakj1fd259a02016-04-16 03:17:097902 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167903 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297904
tfarina42834112016-09-22 13:38:207905 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297907
7908 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017909 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167910 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297911
wezca1070932016-05-26 20:30:527912 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297913
7914 EXPECT_EQ(302, response->headers->response_code());
7915 std::string url;
7916 EXPECT_TRUE(response->headers->IsRedirect(&url));
7917 EXPECT_EQ("http://login.example.com/", url);
7918}
7919
[email protected]4eddbc732012-08-09 05:40:177920// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017921TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037922 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297923
7924 HttpRequestInfo request;
7925 request.method = "GET";
bncce36dca22015-04-21 22:11:237926 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297927
7928 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177929 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7930 "Host: www.example.org:443\r\n"
7931 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297932 };
7933
7934 MockRead data_reads[] = {
7935 MockRead("HTTP/1.1 404 Not Found\r\n"),
7936 MockRead("Content-Length: 23\r\n\r\n"),
7937 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067938 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297939 };
7940
7941 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7942 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067943 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297944
[email protected]bb88e1d32013-05-03 23:11:077945 session_deps_.socket_factory->AddSocketDataProvider(&data);
7946 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297947
[email protected]49639fa2011-12-20 23:22:417948 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297949
danakj1fd259a02016-04-16 03:17:097950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297952
tfarina42834112016-09-22 13:38:207953 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297955
7956 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017957 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297958
ttuttle960fcbf2016-04-19 13:26:327959 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297960}
7961
[email protected]4eddbc732012-08-09 05:40:177962// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017963TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037964 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297965
7966 HttpRequestInfo request;
7967 request.method = "GET";
bncce36dca22015-04-21 22:11:237968 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297969
bncdf80d44fd2016-07-15 20:27:417970 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237971 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417972 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:087973 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297974 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417975 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297976 };
7977
7978 static const char* const kExtraHeaders[] = {
7979 "location",
7980 "http://login.example.com/",
7981 };
bnc42331402016-07-25 13:36:157982 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237983 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:417984 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557985 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297986 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417987 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137988 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297989 };
7990
rch8e6c6c42015-05-01 14:05:137991 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7992 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067993 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367994 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297995
[email protected]bb88e1d32013-05-03 23:11:077996 session_deps_.socket_factory->AddSocketDataProvider(&data);
7997 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297998
[email protected]49639fa2011-12-20 23:22:417999 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298000
danakj1fd259a02016-04-16 03:17:098001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168002 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298003
tfarina42834112016-09-22 13:38:208004 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298006
8007 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018008 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298009
ttuttle960fcbf2016-04-19 13:26:328010 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298011}
8012
[email protected]0c5fb722012-02-28 11:50:358013// Test the request-challenge-retry sequence for basic auth, through
8014// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018015TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358016 HttpRequestInfo request;
8017 request.method = "GET";
bncce36dca22015-04-21 22:11:238018 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358019 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298020 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358021
8022 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038023 session_deps_.proxy_service =
8024 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518025 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078026 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358028
8029 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418030 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238031 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418032 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088033 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388034 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358035
bnc691fda62016-08-12 00:43:168036 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358037 // be issuing -- the final header line contains the credentials.
8038 const char* const kAuthCredentials[] = {
8039 "proxy-authorization", "Basic Zm9vOmJhcg==",
8040 };
bncdf80d44fd2016-07-15 20:27:418041 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348042 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238043 HostPortPair("www.example.org", 443)));
8044 // fetch https://www.example.org/ via HTTP
8045 const char get[] =
8046 "GET / HTTP/1.1\r\n"
8047 "Host: www.example.org\r\n"
8048 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418049 SpdySerializedFrame wrapped_get(
8050 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358051
8052 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418053 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8054 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358055 };
8056
8057 // The proxy responds to the connect with a 407, using a persistent
8058 // connection.
thestig9d3bb0c2015-01-24 00:49:518059 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358060 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358061 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8062 };
bnc42331402016-07-25 13:36:158063 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418064 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358065
bnc42331402016-07-25 13:36:158066 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358067 const char resp[] = "HTTP/1.1 200 OK\r\n"
8068 "Content-Length: 5\r\n\r\n";
8069
bncdf80d44fd2016-07-15 20:27:418070 SpdySerializedFrame wrapped_get_resp(
8071 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8072 SpdySerializedFrame wrapped_body(
8073 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358074 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418075 CreateMockRead(conn_auth_resp, 1, ASYNC),
8076 CreateMockRead(conn_resp, 4, ASYNC),
8077 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8078 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138079 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358080 };
8081
rch8e6c6c42015-05-01 14:05:138082 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8083 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078084 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358085 // Negotiate SPDY to the proxy
8086 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368087 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078088 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358089 // Vanilla SSL to the server
8090 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078091 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358092
8093 TestCompletionCallback callback1;
8094
bnc87dcefc2017-05-25 12:47:588095 auto trans =
8096 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358097
8098 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358100
8101 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018102 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468103 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358104 log.GetEntries(&entries);
8105 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008106 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8107 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358108 ExpectLogContainsSomewhere(
8109 entries, pos,
mikecirone8b85c432016-09-08 19:11:008110 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8111 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358112
8113 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528114 ASSERT_TRUE(response);
8115 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358116 EXPECT_EQ(407, response->headers->response_code());
8117 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528118 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438119 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358120
8121 TestCompletionCallback callback2;
8122
8123 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8124 callback2.callback());
robpercival214763f2016-07-01 23:27:018125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358126
8127 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018128 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358129
8130 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528131 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358132
8133 EXPECT_TRUE(response->headers->IsKeepAlive());
8134 EXPECT_EQ(200, response->headers->response_code());
8135 EXPECT_EQ(5, response->headers->GetContentLength());
8136 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8137
8138 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528139 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358140
[email protected]029c83b62013-01-24 05:28:208141 LoadTimingInfo load_timing_info;
8142 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8143 TestLoadTimingNotReusedWithPac(load_timing_info,
8144 CONNECT_TIMING_HAS_SSL_TIMES);
8145
[email protected]0c5fb722012-02-28 11:50:358146 trans.reset();
8147 session->CloseAllConnections();
8148}
8149
[email protected]7c6f7ba2012-04-03 04:09:298150// Test that an explicitly trusted SPDY proxy can push a resource from an
8151// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018152TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158153 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588154 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158155 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8156 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298157 HttpRequestInfo request;
8158 HttpRequestInfo push_request;
8159
[email protected]7c6f7ba2012-04-03 04:09:298160 request.method = "GET";
bncce36dca22015-04-21 22:11:238161 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298162 push_request.method = "GET";
8163 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8164
tbansal28e68f82016-02-04 02:56:158165 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038166 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158167 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518168 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078169 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508170
inlinechan894515af2016-12-09 02:40:108171 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508172
danakj1fd259a02016-04-16 03:17:098173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298174
bncdf80d44fd2016-07-15 20:27:418175 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458176 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358177 SpdySerializedFrame stream2_priority(
8178 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298179
8180 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418181 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358182 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298183 };
8184
bncdf80d44fd2016-07-15 20:27:418185 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158186 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298187
bncdf80d44fd2016-07-15 20:27:418188 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298189
bncdf80d44fd2016-07-15 20:27:418190 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558191 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438192 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418193 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8194 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298195
8196 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418197 CreateMockRead(stream1_reply, 1, ASYNC),
8198 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358199 CreateMockRead(stream1_body, 4, ASYNC),
8200 CreateMockRead(stream2_body, 5, ASYNC),
8201 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298202 };
8203
rch8e6c6c42015-05-01 14:05:138204 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8205 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078206 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298207 // Negotiate SPDY to the proxy
8208 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368209 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078210 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298211
bnc87dcefc2017-05-25 12:47:588212 auto trans =
8213 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298214 TestCompletionCallback callback;
8215 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298217
8218 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018219 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298220 const HttpResponseInfo* response = trans->GetResponseInfo();
8221
bnc87dcefc2017-05-25 12:47:588222 auto push_trans =
8223 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508224 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298226
8227 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018228 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298229 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8230
wezca1070932016-05-26 20:30:528231 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298232 EXPECT_TRUE(response->headers->IsKeepAlive());
8233
8234 EXPECT_EQ(200, response->headers->response_code());
8235 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8236
8237 std::string response_data;
8238 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018239 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298240 EXPECT_EQ("hello!", response_data);
8241
[email protected]029c83b62013-01-24 05:28:208242 LoadTimingInfo load_timing_info;
8243 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8244 TestLoadTimingNotReusedWithPac(load_timing_info,
8245 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8246
[email protected]7c6f7ba2012-04-03 04:09:298247 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528248 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298249 EXPECT_EQ(200, push_response->headers->response_code());
8250
8251 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018252 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298253 EXPECT_EQ("pushed", response_data);
8254
[email protected]029c83b62013-01-24 05:28:208255 LoadTimingInfo push_load_timing_info;
8256 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8257 TestLoadTimingReusedWithPac(push_load_timing_info);
8258 // The transactions should share a socket ID, despite being for different
8259 // origins.
8260 EXPECT_EQ(load_timing_info.socket_log_id,
8261 push_load_timing_info.socket_log_id);
8262
[email protected]7c6f7ba2012-04-03 04:09:298263 trans.reset();
8264 push_trans.reset();
8265 session->CloseAllConnections();
8266}
8267
[email protected]8c843192012-04-05 07:15:008268// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018269TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158270 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588271 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158272 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8273 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008274 HttpRequestInfo request;
8275
8276 request.method = "GET";
bncce36dca22015-04-21 22:11:238277 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008278
tbansal28e68f82016-02-04 02:56:158279 session_deps_.proxy_service =
8280 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518281 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078282 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508283
8284 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108285 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508286
danakj1fd259a02016-04-16 03:17:098287 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008288
bncdf80d44fd2016-07-15 20:27:418289 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458290 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008291
bncdf80d44fd2016-07-15 20:27:418292 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088293 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008294
8295 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418296 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008297 };
8298
bncdf80d44fd2016-07-15 20:27:418299 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158300 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008301
bncdf80d44fd2016-07-15 20:27:418302 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008303
bncdf80d44fd2016-07-15 20:27:418304 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558305 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008306
8307 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418308 CreateMockRead(stream1_reply, 1, ASYNC),
8309 CreateMockRead(stream2_syn, 2, ASYNC),
8310 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598311 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008312 };
8313
rch8e6c6c42015-05-01 14:05:138314 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8315 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078316 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008317 // Negotiate SPDY to the proxy
8318 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368319 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078320 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008321
bnc87dcefc2017-05-25 12:47:588322 auto trans =
8323 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008324 TestCompletionCallback callback;
8325 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018326 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008327
8328 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018329 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008330 const HttpResponseInfo* response = trans->GetResponseInfo();
8331
wezca1070932016-05-26 20:30:528332 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008333 EXPECT_TRUE(response->headers->IsKeepAlive());
8334
8335 EXPECT_EQ(200, response->headers->response_code());
8336 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8337
8338 std::string response_data;
8339 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018340 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008341 EXPECT_EQ("hello!", response_data);
8342
8343 trans.reset();
8344 session->CloseAllConnections();
8345}
8346
tbansal8ef1d3e2016-02-03 04:05:428347// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8348// resources.
bncd16676a2016-07-20 16:23:018349TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158350 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588351 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158352 proxy_delegate->set_trusted_spdy_proxy(
8353 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8354
tbansal8ef1d3e2016-02-03 04:05:428355 HttpRequestInfo request;
8356
8357 request.method = "GET";
8358 request.url = GURL("http://www.example.org/");
8359
8360 // Configure against https proxy server "myproxy:70".
8361 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8362 BoundTestNetLog log;
8363 session_deps_.net_log = log.bound().net_log();
8364
8365 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108366 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428367
danakj1fd259a02016-04-16 03:17:098368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428369
bncdf80d44fd2016-07-15 20:27:418370 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458371 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358372 SpdySerializedFrame stream2_priority(
8373 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428374
8375 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418376 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358377 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428378 };
8379
bncdf80d44fd2016-07-15 20:27:418380 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158381 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428382
bncdf80d44fd2016-07-15 20:27:418383 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498384 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8385
bncdf80d44fd2016-07-15 20:27:418386 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428387
bncdf80d44fd2016-07-15 20:27:418388 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158389 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428390
bncdf80d44fd2016-07-15 20:27:418391 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428392
8393 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418394 CreateMockRead(stream1_reply, 1, ASYNC),
8395 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358396 CreateMockRead(stream1_body, 4, ASYNC),
8397 CreateMockRead(stream2_body, 5, ASYNC),
8398 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428399 };
8400
8401 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8402 arraysize(spdy_writes));
8403 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8404 // Negotiate SPDY to the proxy
8405 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368406 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428407 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8408
bnc87dcefc2017-05-25 12:47:588409 auto trans =
8410 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428411 TestCompletionCallback callback;
8412 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428414
8415 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018416 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428417 const HttpResponseInfo* response = trans->GetResponseInfo();
8418
wezca1070932016-05-26 20:30:528419 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428420 EXPECT_TRUE(response->headers->IsKeepAlive());
8421
8422 EXPECT_EQ(200, response->headers->response_code());
8423 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8424
8425 std::string response_data;
8426 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018427 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428428 EXPECT_EQ("hello!", response_data);
8429
8430 trans.reset();
8431 session->CloseAllConnections();
8432}
8433
[email protected]2df19bb2010-08-25 20:13:468434// Test HTTPS connections to a site with a bad certificate, going through an
8435// HTTPS proxy
bncd16676a2016-07-20 16:23:018436TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038437 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468438
8439 HttpRequestInfo request;
8440 request.method = "GET";
bncce36dca22015-04-21 22:11:238441 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468442
8443 // Attempt to fetch the URL from a server with a bad cert
8444 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178445 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8446 "Host: www.example.org:443\r\n"
8447 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468448 };
8449
8450 MockRead bad_cert_reads[] = {
8451 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068452 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468453 };
8454
8455 // Attempt to fetch the URL with a good cert
8456 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178457 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8458 "Host: www.example.org:443\r\n"
8459 "Proxy-Connection: keep-alive\r\n\r\n"),
8460 MockWrite("GET / HTTP/1.1\r\n"
8461 "Host: www.example.org\r\n"
8462 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468463 };
8464
8465 MockRead good_cert_reads[] = {
8466 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8467 MockRead("HTTP/1.0 200 OK\r\n"),
8468 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8469 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068470 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468471 };
8472
8473 StaticSocketDataProvider ssl_bad_certificate(
8474 bad_cert_reads, arraysize(bad_cert_reads),
8475 bad_cert_writes, arraysize(bad_cert_writes));
8476 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8477 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068478 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8479 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468480
8481 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078482 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8483 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8484 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468485
8486 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8488 session_deps_.socket_factory->AddSocketDataProvider(&data);
8489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468490
[email protected]49639fa2011-12-20 23:22:418491 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468492
danakj1fd259a02016-04-16 03:17:098493 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468495
tfarina42834112016-09-22 13:38:208496 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468498
8499 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018500 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468501
bnc691fda62016-08-12 00:43:168502 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018503 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468504
8505 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018506 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468507
bnc691fda62016-08-12 00:43:168508 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468509
wezca1070932016-05-26 20:30:528510 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468511 EXPECT_EQ(100, response->headers->GetContentLength());
8512}
8513
bncd16676a2016-07-20 16:23:018514TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428515 HttpRequestInfo request;
8516 request.method = "GET";
bncce36dca22015-04-21 22:11:238517 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438518 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8519 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428520
danakj1fd259a02016-04-16 03:17:098521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278523
[email protected]1c773ea12009-04-28 19:58:428524 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238525 MockWrite(
8526 "GET / HTTP/1.1\r\n"
8527 "Host: www.example.org\r\n"
8528 "Connection: keep-alive\r\n"
8529 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428530 };
8531
8532 // Lastly, the server responds with the actual content.
8533 MockRead data_reads[] = {
8534 MockRead("HTTP/1.0 200 OK\r\n"),
8535 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8536 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068537 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428538 };
8539
[email protected]31a2bfe2010-02-09 08:03:398540 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8541 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078542 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428543
[email protected]49639fa2011-12-20 23:22:418544 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428545
tfarina42834112016-09-22 13:38:208546 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428548
8549 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018550 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428551}
8552
bncd16676a2016-07-20 16:23:018553TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298554 HttpRequestInfo request;
8555 request.method = "GET";
bncce36dca22015-04-21 22:11:238556 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298557 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8558 "Chromium Ultra Awesome X Edition");
8559
rdsmith82957ad2015-09-16 19:42:038560 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168562 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278563
[email protected]da81f132010-08-18 23:39:298564 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178565 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8566 "Host: www.example.org:443\r\n"
8567 "Proxy-Connection: keep-alive\r\n"
8568 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298569 };
8570 MockRead data_reads[] = {
8571 // Return an error, so the transaction stops here (this test isn't
8572 // interested in the rest).
8573 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8574 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8575 MockRead("Proxy-Connection: close\r\n\r\n"),
8576 };
8577
8578 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8579 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078580 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298581
[email protected]49639fa2011-12-20 23:22:418582 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298583
tfarina42834112016-09-22 13:38:208584 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298586
8587 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018588 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298589}
8590
bncd16676a2016-07-20 16:23:018591TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428592 HttpRequestInfo request;
8593 request.method = "GET";
bncce36dca22015-04-21 22:11:238594 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168595 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8596 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428597
danakj1fd259a02016-04-16 03:17:098598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278600
[email protected]1c773ea12009-04-28 19:58:428601 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238602 MockWrite(
8603 "GET / HTTP/1.1\r\n"
8604 "Host: www.example.org\r\n"
8605 "Connection: keep-alive\r\n"
8606 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428607 };
8608
8609 // Lastly, the server responds with the actual content.
8610 MockRead data_reads[] = {
8611 MockRead("HTTP/1.0 200 OK\r\n"),
8612 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8613 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068614 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428615 };
8616
[email protected]31a2bfe2010-02-09 08:03:398617 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8618 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078619 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428620
[email protected]49639fa2011-12-20 23:22:418621 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428622
tfarina42834112016-09-22 13:38:208623 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428625
8626 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018627 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428628}
8629
bncd16676a2016-07-20 16:23:018630TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428631 HttpRequestInfo request;
8632 request.method = "POST";
bncce36dca22015-04-21 22:11:238633 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428634
danakj1fd259a02016-04-16 03:17:098635 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278637
[email protected]1c773ea12009-04-28 19:58:428638 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238639 MockWrite(
8640 "POST / HTTP/1.1\r\n"
8641 "Host: www.example.org\r\n"
8642 "Connection: keep-alive\r\n"
8643 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428644 };
8645
8646 // Lastly, the server responds with the actual content.
8647 MockRead data_reads[] = {
8648 MockRead("HTTP/1.0 200 OK\r\n"),
8649 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8650 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068651 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428652 };
8653
[email protected]31a2bfe2010-02-09 08:03:398654 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8655 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078656 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428657
[email protected]49639fa2011-12-20 23:22:418658 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428659
tfarina42834112016-09-22 13:38:208660 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428662
8663 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018664 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428665}
8666
bncd16676a2016-07-20 16:23:018667TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428668 HttpRequestInfo request;
8669 request.method = "PUT";
bncce36dca22015-04-21 22:11:238670 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428671
danakj1fd259a02016-04-16 03:17:098672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278674
[email protected]1c773ea12009-04-28 19:58:428675 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238676 MockWrite(
8677 "PUT / HTTP/1.1\r\n"
8678 "Host: www.example.org\r\n"
8679 "Connection: keep-alive\r\n"
8680 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428681 };
8682
8683 // Lastly, the server responds with the actual content.
8684 MockRead data_reads[] = {
8685 MockRead("HTTP/1.0 200 OK\r\n"),
8686 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8687 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068688 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428689 };
8690
[email protected]31a2bfe2010-02-09 08:03:398691 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8692 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078693 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428694
[email protected]49639fa2011-12-20 23:22:418695 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428696
tfarina42834112016-09-22 13:38:208697 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428699
8700 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018701 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428702}
8703
bncd16676a2016-07-20 16:23:018704TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428705 HttpRequestInfo request;
8706 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238707 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428708
danakj1fd259a02016-04-16 03:17:098709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278711
[email protected]1c773ea12009-04-28 19:58:428712 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138713 MockWrite("HEAD / HTTP/1.1\r\n"
8714 "Host: www.example.org\r\n"
8715 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428716 };
8717
8718 // Lastly, the server responds with the actual content.
8719 MockRead data_reads[] = {
8720 MockRead("HTTP/1.0 200 OK\r\n"),
8721 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8722 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068723 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428724 };
8725
[email protected]31a2bfe2010-02-09 08:03:398726 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8727 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078728 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428729
[email protected]49639fa2011-12-20 23:22:418730 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428731
tfarina42834112016-09-22 13:38:208732 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428734
8735 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018736 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428737}
8738
bncd16676a2016-07-20 16:23:018739TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428740 HttpRequestInfo request;
8741 request.method = "GET";
bncce36dca22015-04-21 22:11:238742 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428743 request.load_flags = LOAD_BYPASS_CACHE;
8744
danakj1fd259a02016-04-16 03:17:098745 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278747
[email protected]1c773ea12009-04-28 19:58:428748 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238749 MockWrite(
8750 "GET / HTTP/1.1\r\n"
8751 "Host: www.example.org\r\n"
8752 "Connection: keep-alive\r\n"
8753 "Pragma: no-cache\r\n"
8754 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428755 };
8756
8757 // Lastly, the server responds with the actual content.
8758 MockRead data_reads[] = {
8759 MockRead("HTTP/1.0 200 OK\r\n"),
8760 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8761 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068762 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428763 };
8764
[email protected]31a2bfe2010-02-09 08:03:398765 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8766 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078767 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428768
[email protected]49639fa2011-12-20 23:22:418769 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428770
tfarina42834112016-09-22 13:38:208771 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428773
8774 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018775 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428776}
8777
bncd16676a2016-07-20 16:23:018778TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428779 HttpRequestInfo request;
8780 request.method = "GET";
bncce36dca22015-04-21 22:11:238781 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428782 request.load_flags = LOAD_VALIDATE_CACHE;
8783
danakj1fd259a02016-04-16 03:17:098784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278786
[email protected]1c773ea12009-04-28 19:58:428787 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238788 MockWrite(
8789 "GET / HTTP/1.1\r\n"
8790 "Host: www.example.org\r\n"
8791 "Connection: keep-alive\r\n"
8792 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428793 };
8794
8795 // Lastly, the server responds with the actual content.
8796 MockRead data_reads[] = {
8797 MockRead("HTTP/1.0 200 OK\r\n"),
8798 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8799 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068800 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428801 };
8802
[email protected]31a2bfe2010-02-09 08:03:398803 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8804 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078805 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428806
[email protected]49639fa2011-12-20 23:22:418807 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428808
tfarina42834112016-09-22 13:38:208809 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428811
8812 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018813 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428814}
8815
bncd16676a2016-07-20 16:23:018816TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428817 HttpRequestInfo request;
8818 request.method = "GET";
bncce36dca22015-04-21 22:11:238819 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438820 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428821
danakj1fd259a02016-04-16 03:17:098822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278824
[email protected]1c773ea12009-04-28 19:58:428825 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238826 MockWrite(
8827 "GET / HTTP/1.1\r\n"
8828 "Host: www.example.org\r\n"
8829 "Connection: keep-alive\r\n"
8830 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428831 };
8832
8833 // Lastly, the server responds with the actual content.
8834 MockRead data_reads[] = {
8835 MockRead("HTTP/1.0 200 OK\r\n"),
8836 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8837 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068838 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428839 };
8840
[email protected]31a2bfe2010-02-09 08:03:398841 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8842 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078843 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428844
[email protected]49639fa2011-12-20 23:22:418845 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428846
tfarina42834112016-09-22 13:38:208847 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428849
8850 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018851 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428852}
8853
bncd16676a2016-07-20 16:23:018854TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478855 HttpRequestInfo request;
8856 request.method = "GET";
bncce36dca22015-04-21 22:11:238857 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438858 request.extra_headers.SetHeader("referer", "www.foo.com");
8859 request.extra_headers.SetHeader("hEllo", "Kitty");
8860 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478861
danakj1fd259a02016-04-16 03:17:098862 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278864
[email protected]270c6412010-03-29 22:02:478865 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238866 MockWrite(
8867 "GET / HTTP/1.1\r\n"
8868 "Host: www.example.org\r\n"
8869 "Connection: keep-alive\r\n"
8870 "referer: www.foo.com\r\n"
8871 "hEllo: Kitty\r\n"
8872 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478873 };
8874
8875 // Lastly, the server responds with the actual content.
8876 MockRead data_reads[] = {
8877 MockRead("HTTP/1.0 200 OK\r\n"),
8878 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8879 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068880 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478881 };
8882
8883 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8884 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078885 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478886
[email protected]49639fa2011-12-20 23:22:418887 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478888
tfarina42834112016-09-22 13:38:208889 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478891
8892 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018893 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478894}
8895
bncd16676a2016-07-20 16:23:018896TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278897 HttpRequestInfo request;
8898 request.method = "GET";
bncce36dca22015-04-21 22:11:238899 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278900
rdsmith82957ad2015-09-16 19:42:038901 session_deps_.proxy_service =
8902 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518903 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078904 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028905
danakj1fd259a02016-04-16 03:17:098906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028908
[email protected]3cd17242009-06-23 02:59:028909 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8910 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8911
8912 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238913 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8914 MockWrite(
8915 "GET / HTTP/1.1\r\n"
8916 "Host: www.example.org\r\n"
8917 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028918
8919 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068920 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028921 MockRead("HTTP/1.0 200 OK\r\n"),
8922 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8923 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068924 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028925 };
8926
[email protected]31a2bfe2010-02-09 08:03:398927 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8928 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078929 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028930
[email protected]49639fa2011-12-20 23:22:418931 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028932
tfarina42834112016-09-22 13:38:208933 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028935
8936 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018937 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028938
bnc691fda62016-08-12 00:43:168939 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528940 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028941
tbansal2ecbbc72016-10-06 17:15:478942 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208943 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168944 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208945 TestLoadTimingNotReusedWithPac(load_timing_info,
8946 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8947
[email protected]3cd17242009-06-23 02:59:028948 std::string response_text;
bnc691fda62016-08-12 00:43:168949 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018950 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028951 EXPECT_EQ("Payload", response_text);
8952}
8953
bncd16676a2016-07-20 16:23:018954TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278955 HttpRequestInfo request;
8956 request.method = "GET";
bncce36dca22015-04-21 22:11:238957 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278958
rdsmith82957ad2015-09-16 19:42:038959 session_deps_.proxy_service =
8960 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518961 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078962 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028963
danakj1fd259a02016-04-16 03:17:098964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028966
[email protected]3cd17242009-06-23 02:59:028967 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8968 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8969
8970 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238971 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8972 arraysize(write_buffer)),
8973 MockWrite(
8974 "GET / HTTP/1.1\r\n"
8975 "Host: www.example.org\r\n"
8976 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028977
8978 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018979 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8980 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358981 MockRead("HTTP/1.0 200 OK\r\n"),
8982 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8983 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068984 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358985 };
8986
[email protected]31a2bfe2010-02-09 08:03:398987 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8988 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078989 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358990
[email protected]8ddf8322012-02-23 18:08:068991 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078992 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358993
[email protected]49639fa2011-12-20 23:22:418994 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358995
tfarina42834112016-09-22 13:38:208996 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358998
8999 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019000 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359001
[email protected]029c83b62013-01-24 05:28:209002 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169003 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209004 TestLoadTimingNotReusedWithPac(load_timing_info,
9005 CONNECT_TIMING_HAS_SSL_TIMES);
9006
bnc691fda62016-08-12 00:43:169007 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529008 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479009 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359010
9011 std::string response_text;
bnc691fda62016-08-12 00:43:169012 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019013 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359014 EXPECT_EQ("Payload", response_text);
9015}
9016
bncd16676a2016-07-20 16:23:019017TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209018 HttpRequestInfo request;
9019 request.method = "GET";
bncce36dca22015-04-21 22:11:239020 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209021
rdsmith82957ad2015-09-16 19:42:039022 session_deps_.proxy_service =
9023 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519024 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079025 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209026
danakj1fd259a02016-04-16 03:17:099027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169028 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209029
9030 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9031 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9032
9033 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239034 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9035 MockWrite(
9036 "GET / HTTP/1.1\r\n"
9037 "Host: www.example.org\r\n"
9038 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209039
9040 MockRead data_reads[] = {
9041 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9042 MockRead("HTTP/1.0 200 OK\r\n"),
9043 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9044 MockRead("Payload"),
9045 MockRead(SYNCHRONOUS, OK)
9046 };
9047
9048 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9049 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079050 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209051
9052 TestCompletionCallback callback;
9053
tfarina42834112016-09-22 13:38:209054 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209056
9057 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019058 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209059
bnc691fda62016-08-12 00:43:169060 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529061 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209062
9063 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169064 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209065 TestLoadTimingNotReused(load_timing_info,
9066 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9067
9068 std::string response_text;
bnc691fda62016-08-12 00:43:169069 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019070 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209071 EXPECT_EQ("Payload", response_text);
9072}
9073
bncd16676a2016-07-20 16:23:019074TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279075 HttpRequestInfo request;
9076 request.method = "GET";
bncce36dca22015-04-21 22:11:239077 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279078
rdsmith82957ad2015-09-16 19:42:039079 session_deps_.proxy_service =
9080 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519081 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079082 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359083
danakj1fd259a02016-04-16 03:17:099084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359086
[email protected]e0c27be2009-07-15 13:09:359087 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9088 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379089 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239090 0x05, // Version
9091 0x01, // Command (CONNECT)
9092 0x00, // Reserved.
9093 0x03, // Address type (DOMAINNAME).
9094 0x0F, // Length of domain (15)
9095 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9096 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379097 };
[email protected]e0c27be2009-07-15 13:09:359098 const char kSOCKS5OkResponse[] =
9099 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9100
9101 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239102 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9103 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9104 MockWrite(
9105 "GET / HTTP/1.1\r\n"
9106 "Host: www.example.org\r\n"
9107 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359108
9109 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019110 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9111 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359112 MockRead("HTTP/1.0 200 OK\r\n"),
9113 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9114 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069115 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359116 };
9117
[email protected]31a2bfe2010-02-09 08:03:399118 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9119 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079120 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359121
[email protected]49639fa2011-12-20 23:22:419122 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359123
tfarina42834112016-09-22 13:38:209124 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359126
9127 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019128 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359129
bnc691fda62016-08-12 00:43:169130 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529131 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479132 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359133
[email protected]029c83b62013-01-24 05:28:209134 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169135 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209136 TestLoadTimingNotReusedWithPac(load_timing_info,
9137 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9138
[email protected]e0c27be2009-07-15 13:09:359139 std::string response_text;
bnc691fda62016-08-12 00:43:169140 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019141 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359142 EXPECT_EQ("Payload", response_text);
9143}
9144
bncd16676a2016-07-20 16:23:019145TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279146 HttpRequestInfo request;
9147 request.method = "GET";
bncce36dca22015-04-21 22:11:239148 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279149
rdsmith82957ad2015-09-16 19:42:039150 session_deps_.proxy_service =
9151 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519152 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079153 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359154
danakj1fd259a02016-04-16 03:17:099155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359157
[email protected]e0c27be2009-07-15 13:09:359158 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9159 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379160 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239161 0x05, // Version
9162 0x01, // Command (CONNECT)
9163 0x00, // Reserved.
9164 0x03, // Address type (DOMAINNAME).
9165 0x0F, // Length of domain (15)
9166 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9167 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379168 };
9169
[email protected]e0c27be2009-07-15 13:09:359170 const char kSOCKS5OkResponse[] =
9171 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9172
9173 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239174 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9175 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9176 arraysize(kSOCKS5OkRequest)),
9177 MockWrite(
9178 "GET / HTTP/1.1\r\n"
9179 "Host: www.example.org\r\n"
9180 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359181
9182 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019183 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9184 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029185 MockRead("HTTP/1.0 200 OK\r\n"),
9186 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9187 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069188 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029189 };
9190
[email protected]31a2bfe2010-02-09 08:03:399191 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9192 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079193 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029194
[email protected]8ddf8322012-02-23 18:08:069195 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029197
[email protected]49639fa2011-12-20 23:22:419198 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029199
tfarina42834112016-09-22 13:38:209200 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019201 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029202
9203 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019204 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029205
bnc691fda62016-08-12 00:43:169206 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529207 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479208 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029209
[email protected]029c83b62013-01-24 05:28:209210 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169211 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209212 TestLoadTimingNotReusedWithPac(load_timing_info,
9213 CONNECT_TIMING_HAS_SSL_TIMES);
9214
[email protected]3cd17242009-06-23 02:59:029215 std::string response_text;
bnc691fda62016-08-12 00:43:169216 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019217 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029218 EXPECT_EQ("Payload", response_text);
9219}
9220
[email protected]448d4ca52012-03-04 04:12:239221namespace {
9222
[email protected]04e5be32009-06-26 20:00:319223// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069224
9225struct GroupNameTest {
9226 std::string proxy_server;
9227 std::string url;
9228 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189229 bool ssl;
[email protected]2d731a32010-04-29 01:04:069230};
9231
danakj1fd259a02016-04-16 03:17:099232std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079233 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099234 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069235
bnc525e175a2016-06-20 12:36:409236 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539237 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219238 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129239 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219240 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429241 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469242 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069243
9244 return session;
9245}
9246
mmenkee65e7af2015-10-13 17:16:429247int GroupNameTransactionHelper(const std::string& url,
9248 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069249 HttpRequestInfo request;
9250 request.method = "GET";
9251 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069252
bnc691fda62016-08-12 00:43:169253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279254
[email protected]49639fa2011-12-20 23:22:419255 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069256
9257 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209258 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069259}
9260
[email protected]448d4ca52012-03-04 04:12:239261} // namespace
9262
bncd16676a2016-07-20 16:23:019263TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069264 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239265 {
9266 "", // unused
9267 "http://www.example.org/direct",
9268 "www.example.org:80",
9269 false,
9270 },
9271 {
9272 "", // unused
9273 "http://[2001:1418:13:1::25]/direct",
9274 "[2001:1418:13:1::25]:80",
9275 false,
9276 },
[email protected]04e5be32009-06-26 20:00:319277
bncce36dca22015-04-21 22:11:239278 // SSL Tests
9279 {
9280 "", // unused
9281 "https://www.example.org/direct_ssl",
9282 "ssl/www.example.org:443",
9283 true,
9284 },
9285 {
9286 "", // unused
9287 "https://[2001:1418:13:1::25]/direct",
9288 "ssl/[2001:1418:13:1::25]:443",
9289 true,
9290 },
9291 {
9292 "", // unused
bncaa60ff402016-06-22 19:12:429293 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239294 "ssl/host.with.alternate:443",
9295 true,
9296 },
[email protected]2d731a32010-04-29 01:04:069297 };
[email protected]2ff8b312010-04-26 22:20:549298
viettrungluue4a8b882014-10-16 06:17:389299 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039300 session_deps_.proxy_service =
9301 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099302 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409303 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069304
mmenkee65e7af2015-10-13 17:16:429305 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289306 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589307 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139308 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589309 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
9310 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029311 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9312 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489313 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069314
9315 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429316 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189317 if (tests[i].ssl)
9318 EXPECT_EQ(tests[i].expected_group_name,
9319 ssl_conn_pool->last_group_name_received());
9320 else
9321 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289322 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069323 }
[email protected]2d731a32010-04-29 01:04:069324}
9325
bncd16676a2016-07-20 16:23:019326TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069327 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239328 {
9329 "http_proxy",
9330 "http://www.example.org/http_proxy_normal",
9331 "www.example.org:80",
9332 false,
9333 },
[email protected]2d731a32010-04-29 01:04:069334
bncce36dca22015-04-21 22:11:239335 // SSL Tests
9336 {
9337 "http_proxy",
9338 "https://www.example.org/http_connect_ssl",
9339 "ssl/www.example.org:443",
9340 true,
9341 },
[email protected]af3490e2010-10-16 21:02:299342
bncce36dca22015-04-21 22:11:239343 {
9344 "http_proxy",
bncaa60ff402016-06-22 19:12:429345 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239346 "ssl/host.with.alternate:443",
9347 true,
9348 },
[email protected]45499252013-01-23 17:12:569349
bncce36dca22015-04-21 22:11:239350 {
9351 "http_proxy",
9352 "ftp://ftp.google.com/http_proxy_normal",
9353 "ftp/ftp.google.com:21",
9354 false,
9355 },
[email protected]2d731a32010-04-29 01:04:069356 };
9357
viettrungluue4a8b882014-10-16 06:17:389358 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039359 session_deps_.proxy_service =
9360 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099361 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409362 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069363
mmenkee65e7af2015-10-13 17:16:429364 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069365
[email protected]e60e47a2010-07-14 03:37:189366 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139367 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349368 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139369 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349370 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589371 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399372 mock_pool_manager->SetSocketPoolForHTTPProxy(
9373 proxy_host, base::WrapUnique(http_proxy_pool));
9374 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9375 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489376 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069377
9378 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429379 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189380 if (tests[i].ssl)
9381 EXPECT_EQ(tests[i].expected_group_name,
9382 ssl_conn_pool->last_group_name_received());
9383 else
9384 EXPECT_EQ(tests[i].expected_group_name,
9385 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069386 }
[email protected]2d731a32010-04-29 01:04:069387}
9388
bncd16676a2016-07-20 16:23:019389TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069390 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239391 {
9392 "socks4://socks_proxy:1080",
9393 "http://www.example.org/socks4_direct",
9394 "socks4/www.example.org:80",
9395 false,
9396 },
9397 {
9398 "socks5://socks_proxy:1080",
9399 "http://www.example.org/socks5_direct",
9400 "socks5/www.example.org:80",
9401 false,
9402 },
[email protected]2d731a32010-04-29 01:04:069403
bncce36dca22015-04-21 22:11:239404 // SSL Tests
9405 {
9406 "socks4://socks_proxy:1080",
9407 "https://www.example.org/socks4_ssl",
9408 "socks4/ssl/www.example.org:443",
9409 true,
9410 },
9411 {
9412 "socks5://socks_proxy:1080",
9413 "https://www.example.org/socks5_ssl",
9414 "socks5/ssl/www.example.org:443",
9415 true,
9416 },
[email protected]af3490e2010-10-16 21:02:299417
bncce36dca22015-04-21 22:11:239418 {
9419 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429420 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239421 "socks4/ssl/host.with.alternate:443",
9422 true,
9423 },
[email protected]04e5be32009-06-26 20:00:319424 };
9425
viettrungluue4a8b882014-10-16 06:17:389426 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039427 session_deps_.proxy_service =
9428 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099429 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409430 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029431
mmenkee65e7af2015-10-13 17:16:429432 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319433
[email protected]e60e47a2010-07-14 03:37:189434 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139435 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349436 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139437 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349438 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589439 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399440 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9441 proxy_host, base::WrapUnique(socks_conn_pool));
9442 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9443 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489444 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319445
bnc691fda62016-08-12 00:43:169446 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319447
[email protected]2d731a32010-04-29 01:04:069448 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429449 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189450 if (tests[i].ssl)
9451 EXPECT_EQ(tests[i].expected_group_name,
9452 ssl_conn_pool->last_group_name_received());
9453 else
9454 EXPECT_EQ(tests[i].expected_group_name,
9455 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319456 }
9457}
9458
bncd16676a2016-07-20 16:23:019459TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279460 HttpRequestInfo request;
9461 request.method = "GET";
bncce36dca22015-04-21 22:11:239462 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279463
rdsmith82957ad2015-09-16 19:42:039464 session_deps_.proxy_service =
9465 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329466
[email protected]69719062010-01-05 20:09:219467 // This simulates failure resolving all hostnames; that means we will fail
9468 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079469 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329470
danakj1fd259a02016-04-16 03:17:099471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259473
[email protected]49639fa2011-12-20 23:22:419474 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259475
tfarina42834112016-09-22 13:38:209476 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259478
[email protected]9172a982009-06-06 00:30:259479 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019480 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259481}
9482
[email protected]685af592010-05-11 19:31:249483// Base test to make sure that when the load flags for a request specify to
9484// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029485void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079486 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279487 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109488 HttpRequestInfo request_info;
9489 request_info.method = "GET";
9490 request_info.load_flags = load_flags;
9491 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279492
[email protected]a2c2fb92009-07-18 07:31:049493 // Select a host resolver that does caching.
bnc87dcefc2017-05-25 12:47:589494 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329495
danakj1fd259a02016-04-16 03:17:099496 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289498
bncce36dca22015-04-21 22:11:239499 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289500 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299501 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109502 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079503 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239504 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109505 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209506 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479508 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019509 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289510
9511 // Verify that it was added to host cache, by doing a subsequent async lookup
9512 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109513 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079514 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239515 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109516 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209517 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019518 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289519
bncce36dca22015-04-21 22:11:239520 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289521 // we can tell if the next lookup hit the cache, or the "network".
9522 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239523 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289524
9525 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9526 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069527 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399528 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079529 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289530
[email protected]3b9cca42009-06-16 01:08:289531 // Run the request.
tfarina42834112016-09-22 13:38:209532 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019533 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419534 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289535
9536 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239537 // "www.example.org".
robpercival214763f2016-07-01 23:27:019538 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289539}
9540
[email protected]685af592010-05-11 19:31:249541// There are multiple load flags that should trigger the host cache bypass.
9542// Test each in isolation:
bncd16676a2016-07-20 16:23:019543TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249544 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9545}
9546
bncd16676a2016-07-20 16:23:019547TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249548 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9549}
9550
bncd16676a2016-07-20 16:23:019551TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249552 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9553}
9554
[email protected]0877e3d2009-10-17 22:29:579555// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019556TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579557 HttpRequestInfo request;
9558 request.method = "GET";
9559 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579560
9561 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069562 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579563 };
[email protected]31a2bfe2010-02-09 08:03:399564 StaticSocketDataProvider data(NULL, 0,
9565 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079566 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099567 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579568
[email protected]49639fa2011-12-20 23:22:419569 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579570
bnc691fda62016-08-12 00:43:169571 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579572
tfarina42834112016-09-22 13:38:209573 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579575
9576 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019577 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599578
9579 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169580 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599581 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579582}
9583
zmo9528c9f42015-08-04 22:12:089584// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019585TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579586 HttpRequestInfo request;
9587 request.method = "GET";
9588 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579589
9590 MockRead data_reads[] = {
9591 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069592 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579593 };
9594
[email protected]31a2bfe2010-02-09 08:03:399595 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079596 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099597 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579598
[email protected]49639fa2011-12-20 23:22:419599 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579600
bnc691fda62016-08-12 00:43:169601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579602
tfarina42834112016-09-22 13:38:209603 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579605
9606 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019607 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089608
bnc691fda62016-08-12 00:43:169609 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529610 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089611
wezca1070932016-05-26 20:30:529612 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089613 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9614
9615 std::string response_data;
bnc691fda62016-08-12 00:43:169616 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019617 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089618 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599619
9620 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169621 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599622 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579623}
9624
9625// Make sure that a dropped connection while draining the body for auth
9626// restart does the right thing.
bncd16676a2016-07-20 16:23:019627TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579628 HttpRequestInfo request;
9629 request.method = "GET";
bncce36dca22015-04-21 22:11:239630 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579631
9632 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239633 MockWrite(
9634 "GET / HTTP/1.1\r\n"
9635 "Host: www.example.org\r\n"
9636 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579637 };
9638
9639 MockRead data_reads1[] = {
9640 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9641 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9642 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9643 MockRead("Content-Length: 14\r\n\r\n"),
9644 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069645 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579646 };
9647
[email protected]31a2bfe2010-02-09 08:03:399648 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9649 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079650 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579651
bnc691fda62016-08-12 00:43:169652 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579653 // be issuing -- the final header line contains the credentials.
9654 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239655 MockWrite(
9656 "GET / HTTP/1.1\r\n"
9657 "Host: www.example.org\r\n"
9658 "Connection: keep-alive\r\n"
9659 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579660 };
9661
9662 // Lastly, the server responds with the actual content.
9663 MockRead data_reads2[] = {
9664 MockRead("HTTP/1.1 200 OK\r\n"),
9665 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9666 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069667 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579668 };
9669
[email protected]31a2bfe2010-02-09 08:03:399670 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9671 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079672 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579674
[email protected]49639fa2011-12-20 23:22:419675 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579676
bnc691fda62016-08-12 00:43:169677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509678
tfarina42834112016-09-22 13:38:209679 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579681
9682 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019683 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579684
bnc691fda62016-08-12 00:43:169685 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529686 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049687 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579688
[email protected]49639fa2011-12-20 23:22:419689 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579690
bnc691fda62016-08-12 00:43:169691 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579693
9694 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019695 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579696
bnc691fda62016-08-12 00:43:169697 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529698 ASSERT_TRUE(response);
9699 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579700 EXPECT_EQ(100, response->headers->GetContentLength());
9701}
9702
9703// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019704TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039705 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579706
9707 HttpRequestInfo request;
9708 request.method = "GET";
bncce36dca22015-04-21 22:11:239709 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579710
9711 MockRead proxy_reads[] = {
9712 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069713 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579714 };
9715
[email protected]31a2bfe2010-02-09 08:03:399716 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069717 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579718
[email protected]bb88e1d32013-05-03 23:11:079719 session_deps_.socket_factory->AddSocketDataProvider(&data);
9720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579721
[email protected]49639fa2011-12-20 23:22:419722 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579723
[email protected]bb88e1d32013-05-03 23:11:079724 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579725
danakj1fd259a02016-04-16 03:17:099726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169727 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579728
tfarina42834112016-09-22 13:38:209729 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579731
9732 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019733 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579734}
9735
bncd16676a2016-07-20 16:23:019736TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469737 HttpRequestInfo request;
9738 request.method = "GET";
bncce36dca22015-04-21 22:11:239739 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469740
danakj1fd259a02016-04-16 03:17:099741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279743
[email protected]e22e1362009-11-23 21:31:129744 MockRead data_reads[] = {
9745 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069746 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129747 };
[email protected]9492e4a2010-02-24 00:58:469748
9749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079750 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469751
[email protected]49639fa2011-12-20 23:22:419752 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469753
tfarina42834112016-09-22 13:38:209754 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469756
robpercival214763f2016-07-01 23:27:019757 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469758
bnc691fda62016-08-12 00:43:169759 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529760 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469761
wezca1070932016-05-26 20:30:529762 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469763 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9764
9765 std::string response_data;
bnc691fda62016-08-12 00:43:169766 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019767 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129768}
9769
bncd16676a2016-07-20 16:23:019770TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159771 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529772 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149773 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219774 UploadFileElementReader::ScopedOverridingContentLengthForTests
9775 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339776
danakj1fd259a02016-04-16 03:17:099777 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079778 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149779 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079780 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229781 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279782
9783 HttpRequestInfo request;
9784 request.method = "POST";
bncce36dca22015-04-21 22:11:239785 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279786 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279787
danakj1fd259a02016-04-16 03:17:099788 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169789 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339790
9791 MockRead data_reads[] = {
9792 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9793 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069794 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339795 };
[email protected]31a2bfe2010-02-09 08:03:399796 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079797 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339798
[email protected]49639fa2011-12-20 23:22:419799 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339800
tfarina42834112016-09-22 13:38:209801 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339803
9804 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019805 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339806
bnc691fda62016-08-12 00:43:169807 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529808 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339809
maksim.sisove869bf52016-06-23 17:11:529810 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339811
[email protected]dd3aa792013-07-16 19:10:239812 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339813}
9814
bncd16676a2016-07-20 16:23:019815TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159816 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529817 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369818 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:489819 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
9820 base::WriteFile(temp_file, temp_file_content.c_str(),
9821 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119822 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369823
danakj1fd259a02016-04-16 03:17:099824 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079825 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149826 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079827 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229828 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279829
9830 HttpRequestInfo request;
9831 request.method = "POST";
bncce36dca22015-04-21 22:11:239832 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279833 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279834
[email protected]999dd8c2013-11-12 06:45:549835 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369838
[email protected]999dd8c2013-11-12 06:45:549839 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079840 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369841
[email protected]49639fa2011-12-20 23:22:419842 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369843
tfarina42834112016-09-22 13:38:209844 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019845 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369846
9847 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019848 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369849
[email protected]dd3aa792013-07-16 19:10:239850 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369851}
9852
bncd16676a2016-07-20 16:23:019853TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039854 class FakeUploadElementReader : public UploadElementReader {
9855 public:
9856 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209857 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039858
9859 const CompletionCallback& callback() const { return callback_; }
9860
9861 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209862 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039863 callback_ = callback;
9864 return ERR_IO_PENDING;
9865 }
avibf0746c2015-12-09 19:53:149866 uint64_t GetContentLength() const override { return 0; }
9867 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209868 int Read(IOBuffer* buf,
9869 int buf_length,
9870 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039871 return ERR_FAILED;
9872 }
9873
9874 private:
9875 CompletionCallback callback_;
9876 };
9877
9878 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099879 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9880 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229881 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039882
9883 HttpRequestInfo request;
9884 request.method = "POST";
bncce36dca22015-04-21 22:11:239885 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039886 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039887
danakj1fd259a02016-04-16 03:17:099888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:589889 auto trans =
9890 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:039891
9892 StaticSocketDataProvider data;
9893 session_deps_.socket_factory->AddSocketDataProvider(&data);
9894
9895 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209896 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559898 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039899
9900 // Transaction is pending on request body initialization.
9901 ASSERT_FALSE(fake_reader->callback().is_null());
9902
9903 // Return Init()'s result after the transaction gets destroyed.
9904 trans.reset();
9905 fake_reader->callback().Run(OK); // Should not crash.
9906}
9907
[email protected]aeefc9e82010-02-19 16:18:279908// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019909TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279910 HttpRequestInfo request;
9911 request.method = "GET";
bncce36dca22015-04-21 22:11:239912 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279913
9914 // First transaction will request a resource and receive a Basic challenge
9915 // with realm="first_realm".
9916 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239917 MockWrite(
9918 "GET / HTTP/1.1\r\n"
9919 "Host: www.example.org\r\n"
9920 "Connection: keep-alive\r\n"
9921 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279922 };
9923 MockRead data_reads1[] = {
9924 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9925 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9926 "\r\n"),
9927 };
9928
bnc691fda62016-08-12 00:43:169929 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279930 // for first_realm. The server will reject and provide a challenge with
9931 // second_realm.
9932 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239933 MockWrite(
9934 "GET / HTTP/1.1\r\n"
9935 "Host: www.example.org\r\n"
9936 "Connection: keep-alive\r\n"
9937 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9938 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279939 };
9940 MockRead data_reads2[] = {
9941 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9942 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9943 "\r\n"),
9944 };
9945
9946 // This again fails, and goes back to first_realm. Make sure that the
9947 // entry is removed from cache.
9948 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239949 MockWrite(
9950 "GET / HTTP/1.1\r\n"
9951 "Host: www.example.org\r\n"
9952 "Connection: keep-alive\r\n"
9953 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9954 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279955 };
9956 MockRead data_reads3[] = {
9957 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9958 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9959 "\r\n"),
9960 };
9961
9962 // Try one last time (with the correct password) and get the resource.
9963 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239964 MockWrite(
9965 "GET / HTTP/1.1\r\n"
9966 "Host: www.example.org\r\n"
9967 "Connection: keep-alive\r\n"
9968 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9969 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279970 };
9971 MockRead data_reads4[] = {
9972 MockRead("HTTP/1.1 200 OK\r\n"
9973 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509974 "Content-Length: 5\r\n"
9975 "\r\n"
9976 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279977 };
9978
9979 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9980 data_writes1, arraysize(data_writes1));
9981 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9982 data_writes2, arraysize(data_writes2));
9983 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9984 data_writes3, arraysize(data_writes3));
9985 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9986 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079987 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9988 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9989 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9990 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279991
[email protected]49639fa2011-12-20 23:22:419992 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279993
danakj1fd259a02016-04-16 03:17:099994 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169995 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509996
[email protected]aeefc9e82010-02-19 16:18:279997 // Issue the first request with Authorize headers. There should be a
9998 // password prompt for first_realm waiting to be filled in after the
9999 // transaction completes.
tfarina42834112016-09-22 13:38:2010000 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710002 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110003 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610004 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210005 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410006 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210007 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410008 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310009 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410010 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910011 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710012
10013 // Issue the second request with an incorrect password. There should be a
10014 // password prompt for second_realm waiting to be filled in after the
10015 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110016 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610017 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10018 callback2.callback());
robpercival214763f2016-07-01 23:27:0110019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710020 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110021 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610022 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210023 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410024 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210025 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410026 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310027 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410028 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910029 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710030
10031 // Issue the third request with another incorrect password. There should be
10032 // a password prompt for first_realm waiting to be filled in. If the password
10033 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10034 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110035 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610036 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10037 callback3.callback());
robpercival214763f2016-07-01 23:27:0110038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710039 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110040 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610041 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210042 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410043 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210044 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410045 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310046 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410047 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910048 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710049
10050 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110051 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610052 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10053 callback4.callback());
robpercival214763f2016-07-01 23:27:0110054 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710055 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110056 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610057 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210058 ASSERT_TRUE(response);
10059 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710060}
10061
bncd16676a2016-07-20 16:23:0110062TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210063 MockRead data_reads[] = {
10064 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310065 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210066 MockRead("\r\n"),
10067 MockRead("hello world"),
10068 MockRead(SYNCHRONOUS, OK),
10069 };
10070
10071 HttpRequestInfo request;
10072 request.method = "GET";
bncb26024382016-06-29 02:39:4510073 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210074
10075 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210076 session_deps_.socket_factory->AddSocketDataProvider(&data);
10077
bncb26024382016-06-29 02:39:4510078 SSLSocketDataProvider ssl(ASYNC, OK);
10079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10080
bncc958faa2015-07-31 18:14:5210081 TestCompletionCallback callback;
10082
danakj1fd259a02016-04-16 03:17:0910083 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610084 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210085
tfarina42834112016-09-22 13:38:2010086 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210088
bncb26024382016-06-29 02:39:4510089 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010090 HttpServerProperties* http_server_properties =
10091 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410092 EXPECT_TRUE(
10093 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210094
robpercival214763f2016-07-01 23:27:0110095 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210096
bnc691fda62016-08-12 00:43:1610097 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210098 ASSERT_TRUE(response);
10099 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210100 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10101 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210102 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210103
10104 std::string response_data;
bnc691fda62016-08-12 00:43:1610105 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210106 EXPECT_EQ("hello world", response_data);
10107
zhongyic4de03032017-05-19 04:07:3410108 AlternativeServiceInfoVector alternative_service_info_vector =
10109 http_server_properties->GetAlternativeServiceInfos(test_server);
10110 ASSERT_EQ(1u, alternative_service_info_vector.size());
10111 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10112 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410113 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210114}
10115
bnce3dd56f2016-06-01 10:37:1110116// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110117TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110118 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110119 MockRead data_reads[] = {
10120 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310121 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110122 MockRead("\r\n"),
10123 MockRead("hello world"),
10124 MockRead(SYNCHRONOUS, OK),
10125 };
10126
10127 HttpRequestInfo request;
10128 request.method = "GET";
10129 request.url = GURL("http://www.example.org/");
10130 request.load_flags = 0;
10131
10132 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10133 session_deps_.socket_factory->AddSocketDataProvider(&data);
10134
10135 TestCompletionCallback callback;
10136
10137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610138 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110139
10140 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010141 HttpServerProperties* http_server_properties =
10142 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410143 EXPECT_TRUE(
10144 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110145
tfarina42834112016-09-22 13:38:2010146 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110147 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10148 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110149
bnc691fda62016-08-12 00:43:1610150 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110151 ASSERT_TRUE(response);
10152 ASSERT_TRUE(response->headers);
10153 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10154 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210155 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110156
10157 std::string response_data;
bnc691fda62016-08-12 00:43:1610158 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110159 EXPECT_EQ("hello world", response_data);
10160
zhongyic4de03032017-05-19 04:07:3410161 EXPECT_TRUE(
10162 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110163}
10164
bnca86731e2017-04-17 12:31:2810165// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510166// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110167TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510168 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810169 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510170
bnc8bef8da22016-05-30 01:28:2510171 HttpRequestInfo request;
10172 request.method = "GET";
bncb26024382016-06-29 02:39:4510173 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510174 request.load_flags = 0;
10175
10176 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10177 StaticSocketDataProvider first_data;
10178 first_data.set_connect_data(mock_connect);
10179 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510180 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610181 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510183
10184 MockRead data_reads[] = {
10185 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10186 MockRead(ASYNC, OK),
10187 };
10188 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10189 0);
10190 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10191
10192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10193
bnc525e175a2016-06-20 12:36:4010194 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510195 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110196 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10197 444);
bnc8bef8da22016-05-30 01:28:2510198 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110199 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510200 url::SchemeHostPort(request.url), alternative_service, expiration);
10201
bnc691fda62016-08-12 00:43:1610202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510203 TestCompletionCallback callback;
10204
tfarina42834112016-09-22 13:38:2010205 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510206 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110207 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510208}
10209
bnce3dd56f2016-06-01 10:37:1110210// Regression test for https://crbug.com/615497:
10211// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110212TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110213 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110214 HttpRequestInfo request;
10215 request.method = "GET";
10216 request.url = GURL("http://www.example.org/");
10217 request.load_flags = 0;
10218
10219 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10220 StaticSocketDataProvider first_data;
10221 first_data.set_connect_data(mock_connect);
10222 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10223
10224 MockRead data_reads[] = {
10225 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10226 MockRead(ASYNC, OK),
10227 };
10228 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10229 0);
10230 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10231
10232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10233
bnc525e175a2016-06-20 12:36:4010234 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110235 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110236 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110237 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110238 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110239 url::SchemeHostPort(request.url), alternative_service, expiration);
10240
bnc691fda62016-08-12 00:43:1610241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110242 TestCompletionCallback callback;
10243
tfarina42834112016-09-22 13:38:2010244 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110245 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110246 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110247}
10248
bncd16676a2016-07-20 16:23:0110249TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810250 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910251 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010252 HttpServerProperties* http_server_properties =
10253 session->http_server_properties();
bncb26024382016-06-29 02:39:4510254 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110255 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810256 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110257 http_server_properties->SetQuicAlternativeService(
10258 test_server, alternative_service, expiration,
10259 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410260 EXPECT_EQ(
10261 1u,
10262 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810263
10264 // Send a clear header.
10265 MockRead data_reads[] = {
10266 MockRead("HTTP/1.1 200 OK\r\n"),
10267 MockRead("Alt-Svc: clear\r\n"),
10268 MockRead("\r\n"),
10269 MockRead("hello world"),
10270 MockRead(SYNCHRONOUS, OK),
10271 };
10272 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10273 session_deps_.socket_factory->AddSocketDataProvider(&data);
10274
bncb26024382016-06-29 02:39:4510275 SSLSocketDataProvider ssl(ASYNC, OK);
10276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10277
bnc4f575852015-10-14 18:35:0810278 HttpRequestInfo request;
10279 request.method = "GET";
bncb26024382016-06-29 02:39:4510280 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810281
10282 TestCompletionCallback callback;
10283
bnc691fda62016-08-12 00:43:1610284 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810285
tfarina42834112016-09-22 13:38:2010286 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110287 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810288
bnc691fda62016-08-12 00:43:1610289 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210290 ASSERT_TRUE(response);
10291 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810292 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10293 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210294 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810295
10296 std::string response_data;
bnc691fda62016-08-12 00:43:1610297 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810298 EXPECT_EQ("hello world", response_data);
10299
zhongyic4de03032017-05-19 04:07:3410300 EXPECT_TRUE(
10301 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810302}
10303
bncd16676a2016-07-20 16:23:0110304TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210305 MockRead data_reads[] = {
10306 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310307 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10308 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210309 MockRead("hello world"),
10310 MockRead(SYNCHRONOUS, OK),
10311 };
10312
10313 HttpRequestInfo request;
10314 request.method = "GET";
bncb26024382016-06-29 02:39:4510315 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210316
10317 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210318 session_deps_.socket_factory->AddSocketDataProvider(&data);
10319
bncb26024382016-06-29 02:39:4510320 SSLSocketDataProvider ssl(ASYNC, OK);
10321 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10322
bncc958faa2015-07-31 18:14:5210323 TestCompletionCallback callback;
10324
danakj1fd259a02016-04-16 03:17:0910325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210327
tfarina42834112016-09-22 13:38:2010328 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210330
bncb26024382016-06-29 02:39:4510331 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010332 HttpServerProperties* http_server_properties =
10333 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410334 EXPECT_TRUE(
10335 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210336
robpercival214763f2016-07-01 23:27:0110337 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210338
bnc691fda62016-08-12 00:43:1610339 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210340 ASSERT_TRUE(response);
10341 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210342 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10343 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210344 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210345
10346 std::string response_data;
bnc691fda62016-08-12 00:43:1610347 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210348 EXPECT_EQ("hello world", response_data);
10349
zhongyic4de03032017-05-19 04:07:3410350 AlternativeServiceInfoVector alternative_service_info_vector =
10351 http_server_properties->GetAlternativeServiceInfos(test_server);
10352 ASSERT_EQ(2u, alternative_service_info_vector.size());
10353
10354 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
10355 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410356 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410357 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10358 1234);
10359 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5410360 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5210361}
10362
bncd16676a2016-07-20 16:23:0110363TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610364 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210365 HostPortPair alternative("alternative.example.org", 443);
10366 std::string origin_url = "https://origin.example.org:443";
10367 std::string alternative_url = "https://alternative.example.org:443";
10368
10369 // Negotiate HTTP/1.1 with alternative.example.org.
10370 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610371 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10373
10374 // HTTP/1.1 data for request.
10375 MockWrite http_writes[] = {
10376 MockWrite("GET / HTTP/1.1\r\n"
10377 "Host: alternative.example.org\r\n"
10378 "Connection: keep-alive\r\n\r\n"),
10379 };
10380
10381 MockRead http_reads[] = {
10382 MockRead("HTTP/1.1 200 OK\r\n"
10383 "Content-Type: text/html; charset=iso-8859-1\r\n"
10384 "Content-Length: 40\r\n\r\n"
10385 "first HTTP/1.1 response from alternative"),
10386 };
10387 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10388 http_writes, arraysize(http_writes));
10389 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10390
10391 StaticSocketDataProvider data_refused;
10392 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10393 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10394
zhongyi3d4a55e72016-04-22 20:36:4610395 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910396 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010397 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210398 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110399 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210400 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110401 http_server_properties->SetQuicAlternativeService(
10402 server, alternative_service, expiration,
10403 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0210404 // Mark the QUIC alternative service as broken.
10405 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10406
zhongyi48704c182015-12-07 07:52:0210407 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210409 request.method = "GET";
10410 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210411 TestCompletionCallback callback;
10412 NetErrorDetails details;
10413 EXPECT_FALSE(details.quic_broken);
10414
tfarina42834112016-09-22 13:38:2010415 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610416 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210417 EXPECT_TRUE(details.quic_broken);
10418}
10419
bncd16676a2016-07-20 16:23:0110420TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610421 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210422 HostPortPair alternative1("alternative1.example.org", 443);
10423 HostPortPair alternative2("alternative2.example.org", 443);
10424 std::string origin_url = "https://origin.example.org:443";
10425 std::string alternative_url1 = "https://alternative1.example.org:443";
10426 std::string alternative_url2 = "https://alternative2.example.org:443";
10427
10428 // Negotiate HTTP/1.1 with alternative1.example.org.
10429 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610430 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10432
10433 // HTTP/1.1 data for request.
10434 MockWrite http_writes[] = {
10435 MockWrite("GET / HTTP/1.1\r\n"
10436 "Host: alternative1.example.org\r\n"
10437 "Connection: keep-alive\r\n\r\n"),
10438 };
10439
10440 MockRead http_reads[] = {
10441 MockRead("HTTP/1.1 200 OK\r\n"
10442 "Content-Type: text/html; charset=iso-8859-1\r\n"
10443 "Content-Length: 40\r\n\r\n"
10444 "first HTTP/1.1 response from alternative1"),
10445 };
10446 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10447 http_writes, arraysize(http_writes));
10448 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10449
10450 StaticSocketDataProvider data_refused;
10451 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10452 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10453
danakj1fd259a02016-04-16 03:17:0910454 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010455 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210456 session->http_server_properties();
10457
zhongyi3d4a55e72016-04-22 20:36:4610458 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210459 AlternativeServiceInfoVector alternative_service_info_vector;
10460 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10461
bnc3472afd2016-11-17 15:27:2110462 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2110463 alternative_service_info_vector.push_back(
10464 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10465 alternative_service1, expiration,
10466 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2110467 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2110468 alternative_service_info_vector.push_back(
10469 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10470 alternative_service2, expiration,
10471 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0210472
10473 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610474 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210475
10476 // Mark one of the QUIC alternative service as broken.
10477 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410478 EXPECT_EQ(2u,
10479 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210480
zhongyi48704c182015-12-07 07:52:0210481 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610482 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210483 request.method = "GET";
10484 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210485 TestCompletionCallback callback;
10486 NetErrorDetails details;
10487 EXPECT_FALSE(details.quic_broken);
10488
tfarina42834112016-09-22 13:38:2010489 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610490 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210491 EXPECT_FALSE(details.quic_broken);
10492}
10493
bncd16676a2016-07-20 16:23:0110494TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210495 HttpRequestInfo request;
10496 request.method = "GET";
bncb26024382016-06-29 02:39:4510497 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210498
[email protected]d973e99a2012-02-17 21:02:3610499 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210500 StaticSocketDataProvider first_data;
10501 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710502 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510503 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610504 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510505 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210506
10507 MockRead data_reads[] = {
10508 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10509 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610510 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210511 };
10512 StaticSocketDataProvider second_data(
10513 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710514 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210515
danakj1fd259a02016-04-16 03:17:0910516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210517
bnc525e175a2016-06-20 12:36:4010518 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310519 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610520 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110521 // Port must be < 1024, or the header will be ignored (since initial port was
10522 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2110523 // Port is ignored by MockConnect anyway.
10524 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10525 666);
bnc7dc7e1b42015-07-28 14:43:1210526 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110527 http_server_properties->SetHttp2AlternativeService(
10528 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4210529
bnc691fda62016-08-12 00:43:1610530 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110531 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210532
tfarina42834112016-09-22 13:38:2010533 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10535 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210536
bnc691fda62016-08-12 00:43:1610537 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210538 ASSERT_TRUE(response);
10539 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210540 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10541
10542 std::string response_data;
bnc691fda62016-08-12 00:43:1610543 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210544 EXPECT_EQ("hello world", response_data);
10545
zhongyic4de03032017-05-19 04:07:3410546 const AlternativeServiceInfoVector alternative_service_info_vector =
10547 http_server_properties->GetAlternativeServiceInfos(server);
10548 ASSERT_EQ(1u, alternative_service_info_vector.size());
10549 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410550 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410551 EXPECT_TRUE(
10552 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210553}
10554
bnc55ff9da2015-08-19 18:42:3510555// Ensure that we are not allowed to redirect traffic via an alternate protocol
10556// to an unrestricted (port >= 1024) when the original traffic was on a
10557// restricted port (port < 1024). Ensure that we can redirect in all other
10558// cases.
bncd16676a2016-07-20 16:23:0110559TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110560 HttpRequestInfo restricted_port_request;
10561 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510562 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110563 restricted_port_request.load_flags = 0;
10564
[email protected]d973e99a2012-02-17 21:02:3610565 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110566 StaticSocketDataProvider first_data;
10567 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710568 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110569
10570 MockRead data_reads[] = {
10571 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10572 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610573 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110574 };
10575 StaticSocketDataProvider second_data(
10576 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710577 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510578 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610579 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510580 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110581
danakj1fd259a02016-04-16 03:17:0910582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110583
bnc525e175a2016-06-20 12:36:4010584 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310585 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110586 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110587 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10588 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210589 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110590 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610591 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010592 expiration);
[email protected]3912662a32011-10-04 00:51:1110593
bnc691fda62016-08-12 00:43:1610594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110595 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110596
tfarina42834112016-09-22 13:38:2010597 int rv = trans.Start(&restricted_port_request, callback.callback(),
10598 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110600 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110601 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910602}
[email protected]3912662a32011-10-04 00:51:1110603
bnc55ff9da2015-08-19 18:42:3510604// Ensure that we are allowed to redirect traffic via an alternate protocol to
10605// an unrestricted (port >= 1024) when the original traffic was on a restricted
10606// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110607TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710608 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910609
10610 HttpRequestInfo restricted_port_request;
10611 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510612 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910613 restricted_port_request.load_flags = 0;
10614
10615 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10616 StaticSocketDataProvider first_data;
10617 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710618 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910619
10620 MockRead data_reads[] = {
10621 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10622 MockRead("hello world"),
10623 MockRead(ASYNC, OK),
10624 };
10625 StaticSocketDataProvider second_data(
10626 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710627 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510628 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610629 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910631
danakj1fd259a02016-04-16 03:17:0910632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910633
bnc525e175a2016-06-20 12:36:4010634 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910635 session->http_server_properties();
10636 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110637 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10638 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210639 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110640 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610641 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010642 expiration);
[email protected]c54c6962013-02-01 04:53:1910643
bnc691fda62016-08-12 00:43:1610644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910645 TestCompletionCallback callback;
10646
tfarina42834112016-09-22 13:38:2010647 EXPECT_EQ(ERR_IO_PENDING,
10648 trans.Start(&restricted_port_request, callback.callback(),
10649 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910650 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110651 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110652}
10653
bnc55ff9da2015-08-19 18:42:3510654// Ensure that we are not allowed to redirect traffic via an alternate protocol
10655// to an unrestricted (port >= 1024) when the original traffic was on a
10656// restricted port (port < 1024). Ensure that we can redirect in all other
10657// cases.
bncd16676a2016-07-20 16:23:0110658TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110659 HttpRequestInfo restricted_port_request;
10660 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510661 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110662 restricted_port_request.load_flags = 0;
10663
[email protected]d973e99a2012-02-17 21:02:3610664 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110665 StaticSocketDataProvider first_data;
10666 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710667 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110668
10669 MockRead data_reads[] = {
10670 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10671 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610672 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110673 };
10674 StaticSocketDataProvider second_data(
10675 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710676 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110677
bncb26024382016-06-29 02:39:4510678 SSLSocketDataProvider ssl(ASYNC, OK);
10679 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10680
danakj1fd259a02016-04-16 03:17:0910681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110682
bnc525e175a2016-06-20 12:36:4010683 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310684 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110685 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110686 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10687 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210688 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110689 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610690 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010691 expiration);
[email protected]3912662a32011-10-04 00:51:1110692
bnc691fda62016-08-12 00:43:1610693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110694 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110695
tfarina42834112016-09-22 13:38:2010696 int rv = trans.Start(&restricted_port_request, callback.callback(),
10697 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110699 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110700 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110701}
10702
bnc55ff9da2015-08-19 18:42:3510703// Ensure that we are not allowed to redirect traffic via an alternate protocol
10704// to an unrestricted (port >= 1024) when the original traffic was on a
10705// restricted port (port < 1024). Ensure that we can redirect in all other
10706// cases.
bncd16676a2016-07-20 16:23:0110707TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110708 HttpRequestInfo unrestricted_port_request;
10709 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510710 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110711 unrestricted_port_request.load_flags = 0;
10712
[email protected]d973e99a2012-02-17 21:02:3610713 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110714 StaticSocketDataProvider first_data;
10715 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710716 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110717
10718 MockRead data_reads[] = {
10719 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10720 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610721 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110722 };
10723 StaticSocketDataProvider second_data(
10724 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710725 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510726 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610727 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110729
danakj1fd259a02016-04-16 03:17:0910730 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110731
bnc525e175a2016-06-20 12:36:4010732 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310733 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110734 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110735 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10736 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210737 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110738 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610739 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010740 expiration);
[email protected]3912662a32011-10-04 00:51:1110741
bnc691fda62016-08-12 00:43:1610742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110743 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110744
bnc691fda62016-08-12 00:43:1610745 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010746 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110748 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110749 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110750}
10751
bnc55ff9da2015-08-19 18:42:3510752// Ensure that we are not allowed to redirect traffic via an alternate protocol
10753// to an unrestricted (port >= 1024) when the original traffic was on a
10754// restricted port (port < 1024). Ensure that we can redirect in all other
10755// cases.
bncd16676a2016-07-20 16:23:0110756TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110757 HttpRequestInfo unrestricted_port_request;
10758 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510759 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110760 unrestricted_port_request.load_flags = 0;
10761
[email protected]d973e99a2012-02-17 21:02:3610762 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110763 StaticSocketDataProvider first_data;
10764 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710765 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110766
10767 MockRead data_reads[] = {
10768 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10769 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610770 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110771 };
10772 StaticSocketDataProvider second_data(
10773 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710774 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110775
bncb26024382016-06-29 02:39:4510776 SSLSocketDataProvider ssl(ASYNC, OK);
10777 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10778
danakj1fd259a02016-04-16 03:17:0910779 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110780
bnc525e175a2016-06-20 12:36:4010781 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310782 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210783 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110784 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10785 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210786 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110787 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610788 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010789 expiration);
[email protected]3912662a32011-10-04 00:51:1110790
bnc691fda62016-08-12 00:43:1610791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110792 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110793
bnc691fda62016-08-12 00:43:1610794 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010795 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110797 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110798 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110799}
10800
bnc55ff9da2015-08-19 18:42:3510801// Ensure that we are not allowed to redirect traffic via an alternate protocol
10802// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10803// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110804TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210805 HttpRequestInfo request;
10806 request.method = "GET";
bncce36dca22015-04-21 22:11:2310807 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210808
10809 // The alternate protocol request will error out before we attempt to connect,
10810 // so only the standard HTTP request will try to connect.
10811 MockRead data_reads[] = {
10812 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10813 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610814 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210815 };
10816 StaticSocketDataProvider data(
10817 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710818 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210819
danakj1fd259a02016-04-16 03:17:0910820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210821
bnc525e175a2016-06-20 12:36:4010822 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210823 session->http_server_properties();
10824 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110825 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10826 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210827 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110828 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610829 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210830
bnc691fda62016-08-12 00:43:1610831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210832 TestCompletionCallback callback;
10833
tfarina42834112016-09-22 13:38:2010834 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210836 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110837 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210838
bnc691fda62016-08-12 00:43:1610839 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210840 ASSERT_TRUE(response);
10841 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210842 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10843
10844 std::string response_data;
bnc691fda62016-08-12 00:43:1610845 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210846 EXPECT_EQ("hello world", response_data);
10847}
10848
bncd16676a2016-07-20 16:23:0110849TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410850 HttpRequestInfo request;
10851 request.method = "GET";
bncb26024382016-06-29 02:39:4510852 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410853
10854 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210855 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310856 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210857 MockRead("\r\n"),
10858 MockRead("hello world"),
10859 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10860 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410861
10862 StaticSocketDataProvider first_transaction(
10863 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710864 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510865 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610866 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510867 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410868
bnc032658ba2016-09-26 18:17:1510869 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410870
bncdf80d44fd2016-07-15 20:27:4110871 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510872 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110873 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410874
bnc42331402016-07-25 13:36:1510875 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110876 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410877 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110878 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410879 };
10880
rch8e6c6c42015-05-01 14:05:1310881 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10882 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710883 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410884
[email protected]d973e99a2012-02-17 21:02:3610885 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510886 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10887 NULL, 0, NULL, 0);
10888 hanging_non_alternate_protocol_socket.set_connect_data(
10889 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710890 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510891 &hanging_non_alternate_protocol_socket);
10892
[email protected]49639fa2011-12-20 23:22:4110893 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410894
danakj1fd259a02016-04-16 03:17:0910895 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810896 auto trans =
10897 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410898
tfarina42834112016-09-22 13:38:2010899 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10901 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410902
10903 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210904 ASSERT_TRUE(response);
10905 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410906 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10907
10908 std::string response_data;
robpercival214763f2016-07-01 23:27:0110909 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410910 EXPECT_EQ("hello world", response_data);
10911
bnc87dcefc2017-05-25 12:47:5810912 trans =
10913 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410914
tfarina42834112016-09-22 13:38:2010915 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110916 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10917 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410918
10919 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210920 ASSERT_TRUE(response);
10921 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210922 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310923 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210924 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410925
robpercival214763f2016-07-01 23:27:0110926 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410927 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410928}
10929
bncd16676a2016-07-20 16:23:0110930TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510931 HttpRequestInfo request;
10932 request.method = "GET";
bncb26024382016-06-29 02:39:4510933 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510934
bncb26024382016-06-29 02:39:4510935 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510936 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210937 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310938 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210939 MockRead("\r\n"),
10940 MockRead("hello world"),
10941 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10942 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510943 };
10944
bncb26024382016-06-29 02:39:4510945 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10946 0);
10947 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510948
bncb26024382016-06-29 02:39:4510949 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10950 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10951
10952 // Second transaction starts an alternative and a non-alternative Job.
10953 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610954 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810955 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10956 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810957 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10958
10959 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10960 hanging_socket2.set_connect_data(never_finishing_connect);
10961 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510962
bncb26024382016-06-29 02:39:4510963 // Third transaction starts an alternative and a non-alternative job.
10964 // The non-alternative job hangs, but the alternative one succeeds.
10965 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110966 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510967 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110968 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510969 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510970 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110971 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510972 };
bnc42331402016-07-25 13:36:1510973 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110974 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510975 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110976 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510977 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110978 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10979 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310980 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510981 };
10982
rch8e6c6c42015-05-01 14:05:1310983 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10984 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710985 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510986
bnc032658ba2016-09-26 18:17:1510987 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510988
mmenkecc2298e2015-12-07 18:20:1810989 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10990 hanging_socket3.set_connect_data(never_finishing_connect);
10991 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510992
danakj1fd259a02016-04-16 03:17:0910993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110994 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010995 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510996
tfarina42834112016-09-22 13:38:2010997 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10999 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511000
11001 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211002 ASSERT_TRUE(response);
11003 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511004 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11005
11006 std::string response_data;
robpercival214763f2016-07-01 23:27:0111007 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511008 EXPECT_EQ("hello world", response_data);
11009
[email protected]49639fa2011-12-20 23:22:4111010 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011011 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011012 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511014
[email protected]49639fa2011-12-20 23:22:4111015 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011016 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011017 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511019
robpercival214763f2016-07-01 23:27:0111020 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11021 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511022
11023 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211024 ASSERT_TRUE(response);
11025 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211026 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511027 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211028 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111029 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511030 EXPECT_EQ("hello!", response_data);
11031
11032 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211033 ASSERT_TRUE(response);
11034 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211035 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511036 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211037 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111038 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511039 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511040}
11041
bncd16676a2016-07-20 16:23:0111042TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511043 HttpRequestInfo request;
11044 request.method = "GET";
bncb26024382016-06-29 02:39:4511045 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511046
11047 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211048 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311049 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211050 MockRead("\r\n"),
11051 MockRead("hello world"),
11052 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11053 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511054 };
11055
11056 StaticSocketDataProvider first_transaction(
11057 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711058 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511059
[email protected]8ddf8322012-02-23 18:08:0611060 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511062
[email protected]d973e99a2012-02-17 21:02:3611063 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511064 StaticSocketDataProvider hanging_alternate_protocol_socket(
11065 NULL, 0, NULL, 0);
11066 hanging_alternate_protocol_socket.set_connect_data(
11067 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711068 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511069 &hanging_alternate_protocol_socket);
11070
bncb26024382016-06-29 02:39:4511071 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811072 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11073 NULL, 0);
11074 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511075 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511076
[email protected]49639fa2011-12-20 23:22:4111077 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511078
danakj1fd259a02016-04-16 03:17:0911079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811080 auto trans =
11081 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511082
tfarina42834112016-09-22 13:38:2011083 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11085 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511086
11087 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211088 ASSERT_TRUE(response);
11089 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511090 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11091
11092 std::string response_data;
robpercival214763f2016-07-01 23:27:0111093 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511094 EXPECT_EQ("hello world", response_data);
11095
bnc87dcefc2017-05-25 12:47:5811096 trans =
11097 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511098
tfarina42834112016-09-22 13:38:2011099 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111100 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11101 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511102
11103 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211104 ASSERT_TRUE(response);
11105 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511106 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11107 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211108 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511109
robpercival214763f2016-07-01 23:27:0111110 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511111 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511112}
11113
[email protected]631f1322010-04-30 17:59:1111114class CapturingProxyResolver : public ProxyResolver {
11115 public:
sammce90c9212015-05-27 23:43:3511116 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011117 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111118
dchengb03027d2014-10-21 12:00:2011119 int GetProxyForURL(const GURL& url,
11120 ProxyInfo* results,
11121 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511122 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011123 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011124 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11125 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211126 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111127 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211128 return OK;
[email protected]631f1322010-04-30 17:59:1111129 }
11130
[email protected]24476402010-07-20 20:55:1711131 const std::vector<GURL>& resolved() const { return resolved_; }
11132
11133 private:
[email protected]631f1322010-04-30 17:59:1111134 std::vector<GURL> resolved_;
11135
11136 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11137};
11138
sammce64b2362015-04-29 03:50:2311139class CapturingProxyResolverFactory : public ProxyResolverFactory {
11140 public:
11141 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11142 : ProxyResolverFactory(false), resolver_(resolver) {}
11143
11144 int CreateProxyResolver(
11145 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911146 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311147 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911148 std::unique_ptr<Request>* request) override {
bnc87dcefc2017-05-25 12:47:5811149 *resolver = base::MakeUnique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311150 return OK;
11151 }
11152
11153 private:
11154 ProxyResolver* resolver_;
11155};
11156
bnc2e884782016-08-11 19:45:1911157// Test that proxy is resolved using the origin url,
11158// regardless of the alternative server.
11159TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11160 // Configure proxy to bypass www.example.org, which is the origin URL.
11161 ProxyConfig proxy_config;
11162 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11163 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11164 auto proxy_config_service =
11165 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11166
11167 CapturingProxyResolver capturing_proxy_resolver;
11168 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11169 &capturing_proxy_resolver);
11170
11171 TestNetLog net_log;
11172
11173 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11174 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11175 &net_log);
11176
11177 session_deps_.net_log = &net_log;
11178
11179 // Configure alternative service with a hostname that is not bypassed by the
11180 // proxy.
11181 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11182 HttpServerProperties* http_server_properties =
11183 session->http_server_properties();
11184 url::SchemeHostPort server("https", "www.example.org", 443);
11185 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111186 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911187 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111188 http_server_properties->SetHttp2AlternativeService(
11189 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911190
11191 // Non-alternative job should hang.
11192 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11193 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11194 nullptr, 0);
11195 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11196 session_deps_.socket_factory->AddSocketDataProvider(
11197 &hanging_alternate_protocol_socket);
11198
bnc032658ba2016-09-26 18:17:1511199 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911200
11201 HttpRequestInfo request;
11202 request.method = "GET";
11203 request.url = GURL("https://www.example.org/");
11204 request.load_flags = 0;
11205
11206 SpdySerializedFrame req(
11207 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11208
11209 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11210
11211 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11212 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11213 MockRead spdy_reads[] = {
11214 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11215 };
11216
11217 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11218 arraysize(spdy_writes));
11219 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11220
11221 TestCompletionCallback callback;
11222
11223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11224
tfarina42834112016-09-22 13:38:2011225 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911226 EXPECT_THAT(callback.GetResult(rv), IsOk());
11227
11228 const HttpResponseInfo* response = trans.GetResponseInfo();
11229 ASSERT_TRUE(response);
11230 ASSERT_TRUE(response->headers);
11231 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11232 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211233 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911234
11235 std::string response_data;
11236 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11237 EXPECT_EQ("hello!", response_data);
11238
11239 // Origin host bypasses proxy, no resolution should have happened.
11240 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11241}
11242
bncd16676a2016-07-20 16:23:0111243TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111244 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211245 proxy_config.set_auto_detect(true);
11246 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111247
sammc5dd160c2015-04-02 02:43:1311248 CapturingProxyResolver capturing_proxy_resolver;
bnc87dcefc2017-05-25 12:47:5811249 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11250 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11251 base::MakeUnique<CapturingProxyResolverFactory>(
11252 &capturing_proxy_resolver),
11253 nullptr);
vishal.b62985ca92015-04-17 08:45:5111254 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711255 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111256
11257 HttpRequestInfo request;
11258 request.method = "GET";
bncb26024382016-06-29 02:39:4511259 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111260
11261 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211262 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311263 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211264 MockRead("\r\n"),
11265 MockRead("hello world"),
11266 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11267 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111268 };
11269
11270 StaticSocketDataProvider first_transaction(
11271 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711272 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511273 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611274 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111276
bnc032658ba2016-09-26 18:17:1511277 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111278
bncdf80d44fd2016-07-15 20:27:4111279 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511280 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111281 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311282 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511283 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11284 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311285 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111286 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111287 };
11288
[email protected]d911f1b2010-05-05 22:39:4211289 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11290
bnc42331402016-07-25 13:36:1511291 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111292 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111293 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111294 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11295 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111296 };
11297
rch8e6c6c42015-05-01 14:05:1311298 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11299 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711300 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111301
[email protected]d973e99a2012-02-17 21:02:3611302 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511303 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11304 NULL, 0, NULL, 0);
11305 hanging_non_alternate_protocol_socket.set_connect_data(
11306 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711307 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511308 &hanging_non_alternate_protocol_socket);
11309
[email protected]49639fa2011-12-20 23:22:4111310 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111311
danakj1fd259a02016-04-16 03:17:0911312 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811313 auto trans =
11314 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111315
tfarina42834112016-09-22 13:38:2011316 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11318 EXPECT_THAT(callback.WaitForResult(), IsOk());
11319
11320 const HttpResponseInfo* response = trans->GetResponseInfo();
11321 ASSERT_TRUE(response);
11322 ASSERT_TRUE(response->headers);
11323 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11324 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211325 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111326
11327 std::string response_data;
11328 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11329 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111330
bnc87dcefc2017-05-25 12:47:5811331 trans =
11332 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111333
tfarina42834112016-09-22 13:38:2011334 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111335 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11336 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111337
mmenkea2dcd3bf2016-08-16 21:49:4111338 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211339 ASSERT_TRUE(response);
11340 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211341 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311342 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211343 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111344
robpercival214763f2016-07-01 23:27:0111345 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111346 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511347 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11348 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311349 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311350 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311351 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111352
[email protected]029c83b62013-01-24 05:28:2011353 LoadTimingInfo load_timing_info;
11354 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11355 TestLoadTimingNotReusedWithPac(load_timing_info,
11356 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111357}
[email protected]631f1322010-04-30 17:59:1111358
bncd16676a2016-07-20 16:23:0111359TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811360 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411361 HttpRequestInfo request;
11362 request.method = "GET";
bncb26024382016-06-29 02:39:4511363 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411364
11365 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211366 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311367 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211368 MockRead("\r\n"),
11369 MockRead("hello world"),
11370 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411371 };
11372
11373 StaticSocketDataProvider first_transaction(
11374 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711375 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511376 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611377 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411379
bnc032658ba2016-09-26 18:17:1511380 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411381
bncdf80d44fd2016-07-15 20:27:4111382 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511383 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111384 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411385
bnc42331402016-07-25 13:36:1511386 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111387 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411388 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111389 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411390 };
11391
rch8e6c6c42015-05-01 14:05:1311392 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11393 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711394 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411395
[email protected]83039bb2011-12-09 18:43:5511396 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411397
danakj1fd259a02016-04-16 03:17:0911398 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411399
bnc87dcefc2017-05-25 12:47:5811400 auto trans =
11401 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411402
tfarina42834112016-09-22 13:38:2011403 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111404 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11405 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411406
11407 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211408 ASSERT_TRUE(response);
11409 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411410 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11411
11412 std::string response_data;
robpercival214763f2016-07-01 23:27:0111413 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411414 EXPECT_EQ("hello world", response_data);
11415
11416 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511417 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011418 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311419 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711420 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011421 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811422
bnc87dcefc2017-05-25 12:47:5811423 trans =
11424 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411425
tfarina42834112016-09-22 13:38:2011426 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111427 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11428 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411429
11430 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211431 ASSERT_TRUE(response);
11432 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211433 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311434 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211435 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411436
robpercival214763f2016-07-01 23:27:0111437 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411438 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211439}
11440
[email protected]044de0642010-06-17 10:42:1511441// GenerateAuthToken is a mighty big test.
11442// It tests all permutation of GenerateAuthToken behavior:
11443// - Synchronous and Asynchronous completion.
11444// - OK or error on completion.
11445// - Direct connection, non-authenticating proxy, and authenticating proxy.
11446// - HTTP or HTTPS backend (to include proxy tunneling).
11447// - Non-authenticating and authenticating backend.
11448//
[email protected]fe3b7dc2012-02-03 19:52:0911449// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511450// problems generating an auth token for an authenticating proxy, we don't
11451// need to test all permutations of the backend server).
11452//
11453// The test proceeds by going over each of the configuration cases, and
11454// potentially running up to three rounds in each of the tests. The TestConfig
11455// specifies both the configuration for the test as well as the expectations
11456// for the results.
bncd16676a2016-07-20 16:23:0111457TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011458 static const char kServer[] = "http://www.example.com";
11459 static const char kSecureServer[] = "https://www.example.com";
11460 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511461
11462 enum AuthTiming {
11463 AUTH_NONE,
11464 AUTH_SYNC,
11465 AUTH_ASYNC,
11466 };
11467
11468 const MockWrite kGet(
11469 "GET / HTTP/1.1\r\n"
11470 "Host: www.example.com\r\n"
11471 "Connection: keep-alive\r\n\r\n");
11472 const MockWrite kGetProxy(
11473 "GET http://www.example.com/ HTTP/1.1\r\n"
11474 "Host: www.example.com\r\n"
11475 "Proxy-Connection: keep-alive\r\n\r\n");
11476 const MockWrite kGetAuth(
11477 "GET / HTTP/1.1\r\n"
11478 "Host: www.example.com\r\n"
11479 "Connection: keep-alive\r\n"
11480 "Authorization: auth_token\r\n\r\n");
11481 const MockWrite kGetProxyAuth(
11482 "GET http://www.example.com/ HTTP/1.1\r\n"
11483 "Host: www.example.com\r\n"
11484 "Proxy-Connection: keep-alive\r\n"
11485 "Proxy-Authorization: auth_token\r\n\r\n");
11486 const MockWrite kGetAuthThroughProxy(
11487 "GET http://www.example.com/ HTTP/1.1\r\n"
11488 "Host: www.example.com\r\n"
11489 "Proxy-Connection: keep-alive\r\n"
11490 "Authorization: auth_token\r\n\r\n");
11491 const MockWrite kGetAuthWithProxyAuth(
11492 "GET http://www.example.com/ HTTP/1.1\r\n"
11493 "Host: www.example.com\r\n"
11494 "Proxy-Connection: keep-alive\r\n"
11495 "Proxy-Authorization: auth_token\r\n"
11496 "Authorization: auth_token\r\n\r\n");
11497 const MockWrite kConnect(
11498 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711499 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511500 "Proxy-Connection: keep-alive\r\n\r\n");
11501 const MockWrite kConnectProxyAuth(
11502 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711503 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511504 "Proxy-Connection: keep-alive\r\n"
11505 "Proxy-Authorization: auth_token\r\n\r\n");
11506
11507 const MockRead kSuccess(
11508 "HTTP/1.1 200 OK\r\n"
11509 "Content-Type: text/html; charset=iso-8859-1\r\n"
11510 "Content-Length: 3\r\n\r\n"
11511 "Yes");
11512 const MockRead kFailure(
11513 "Should not be called.");
11514 const MockRead kServerChallenge(
11515 "HTTP/1.1 401 Unauthorized\r\n"
11516 "WWW-Authenticate: Mock realm=server\r\n"
11517 "Content-Type: text/html; charset=iso-8859-1\r\n"
11518 "Content-Length: 14\r\n\r\n"
11519 "Unauthorized\r\n");
11520 const MockRead kProxyChallenge(
11521 "HTTP/1.1 407 Unauthorized\r\n"
11522 "Proxy-Authenticate: Mock realm=proxy\r\n"
11523 "Proxy-Connection: close\r\n"
11524 "Content-Type: text/html; charset=iso-8859-1\r\n"
11525 "Content-Length: 14\r\n\r\n"
11526 "Unauthorized\r\n");
11527 const MockRead kProxyConnected(
11528 "HTTP/1.1 200 Connection Established\r\n\r\n");
11529
11530 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11531 // no constructors, but the C++ compiler on Windows warns about
11532 // unspecified data in compound literals. So, moved to using constructors,
11533 // and TestRound's created with the default constructor should not be used.
11534 struct TestRound {
11535 TestRound()
11536 : expected_rv(ERR_UNEXPECTED),
11537 extra_write(NULL),
11538 extra_read(NULL) {
11539 }
11540 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11541 int expected_rv_arg)
11542 : write(write_arg),
11543 read(read_arg),
11544 expected_rv(expected_rv_arg),
11545 extra_write(NULL),
11546 extra_read(NULL) {
11547 }
11548 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11549 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111550 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511551 : write(write_arg),
11552 read(read_arg),
11553 expected_rv(expected_rv_arg),
11554 extra_write(extra_write_arg),
11555 extra_read(extra_read_arg) {
11556 }
11557 MockWrite write;
11558 MockRead read;
11559 int expected_rv;
11560 const MockWrite* extra_write;
11561 const MockRead* extra_read;
11562 };
11563
11564 static const int kNoSSL = 500;
11565
11566 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111567 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111568 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511569 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111570 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111571 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511572 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111573 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511574 int num_auth_rounds;
11575 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611576 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511577 } test_configs[] = {
asankac93076192016-10-03 15:46:0211578 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111579 {__LINE__,
11580 nullptr,
asankac93076192016-10-03 15:46:0211581 AUTH_NONE,
11582 OK,
11583 kServer,
11584 AUTH_NONE,
11585 OK,
11586 1,
11587 kNoSSL,
11588 {TestRound(kGet, kSuccess, OK)}},
11589 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111590 {__LINE__,
11591 nullptr,
asankac93076192016-10-03 15:46:0211592 AUTH_NONE,
11593 OK,
11594 kServer,
11595 AUTH_SYNC,
11596 OK,
11597 2,
11598 kNoSSL,
11599 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511600 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111601 {__LINE__,
11602 nullptr,
asankac93076192016-10-03 15:46:0211603 AUTH_NONE,
11604 OK,
11605 kServer,
11606 AUTH_SYNC,
11607 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611608 3,
11609 kNoSSL,
11610 {TestRound(kGet, kServerChallenge, OK),
11611 TestRound(kGet, kServerChallenge, OK),
11612 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111613 {__LINE__,
11614 nullptr,
asankae2257db2016-10-11 22:03:1611615 AUTH_NONE,
11616 OK,
11617 kServer,
11618 AUTH_SYNC,
11619 ERR_UNSUPPORTED_AUTH_SCHEME,
11620 2,
11621 kNoSSL,
11622 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111623 {__LINE__,
11624 nullptr,
asankae2257db2016-10-11 22:03:1611625 AUTH_NONE,
11626 OK,
11627 kServer,
11628 AUTH_SYNC,
11629 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11630 2,
11631 kNoSSL,
11632 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111633 {__LINE__,
11634 kProxy,
asankae2257db2016-10-11 22:03:1611635 AUTH_SYNC,
11636 ERR_FAILED,
11637 kServer,
11638 AUTH_NONE,
11639 OK,
11640 2,
11641 kNoSSL,
11642 {TestRound(kGetProxy, kProxyChallenge, OK),
11643 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111644 {__LINE__,
11645 kProxy,
asankae2257db2016-10-11 22:03:1611646 AUTH_ASYNC,
11647 ERR_FAILED,
11648 kServer,
11649 AUTH_NONE,
11650 OK,
11651 2,
11652 kNoSSL,
11653 {TestRound(kGetProxy, kProxyChallenge, OK),
11654 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111655 {__LINE__,
11656 nullptr,
asankae2257db2016-10-11 22:03:1611657 AUTH_NONE,
11658 OK,
11659 kServer,
11660 AUTH_SYNC,
11661 ERR_FAILED,
asankac93076192016-10-03 15:46:0211662 2,
11663 kNoSSL,
11664 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611665 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111666 {__LINE__,
11667 nullptr,
asankae2257db2016-10-11 22:03:1611668 AUTH_NONE,
11669 OK,
11670 kServer,
11671 AUTH_ASYNC,
11672 ERR_FAILED,
11673 2,
11674 kNoSSL,
11675 {TestRound(kGet, kServerChallenge, OK),
11676 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111677 {__LINE__,
11678 nullptr,
asankac93076192016-10-03 15:46:0211679 AUTH_NONE,
11680 OK,
11681 kServer,
11682 AUTH_ASYNC,
11683 OK,
11684 2,
11685 kNoSSL,
11686 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511687 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111688 {__LINE__,
11689 nullptr,
asankac93076192016-10-03 15:46:0211690 AUTH_NONE,
11691 OK,
11692 kServer,
11693 AUTH_ASYNC,
11694 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611695 3,
asankac93076192016-10-03 15:46:0211696 kNoSSL,
11697 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611698 // The second round uses a HttpAuthHandlerMock that always succeeds.
11699 TestRound(kGet, kServerChallenge, OK),
11700 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211701 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111702 {__LINE__,
11703 kProxy,
asankac93076192016-10-03 15:46:0211704 AUTH_NONE,
11705 OK,
11706 kServer,
11707 AUTH_NONE,
11708 OK,
11709 1,
11710 kNoSSL,
11711 {TestRound(kGetProxy, kSuccess, OK)}},
11712 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111713 {__LINE__,
11714 kProxy,
asankac93076192016-10-03 15:46:0211715 AUTH_NONE,
11716 OK,
11717 kServer,
11718 AUTH_SYNC,
11719 OK,
11720 2,
11721 kNoSSL,
11722 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511723 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111724 {__LINE__,
11725 kProxy,
asankac93076192016-10-03 15:46:0211726 AUTH_NONE,
11727 OK,
11728 kServer,
11729 AUTH_SYNC,
11730 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611731 3,
asankac93076192016-10-03 15:46:0211732 kNoSSL,
11733 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611734 TestRound(kGetProxy, kServerChallenge, OK),
11735 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111736 {__LINE__,
11737 kProxy,
asankac93076192016-10-03 15:46:0211738 AUTH_NONE,
11739 OK,
11740 kServer,
11741 AUTH_ASYNC,
11742 OK,
11743 2,
11744 kNoSSL,
11745 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511746 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111747 {__LINE__,
11748 kProxy,
asankac93076192016-10-03 15:46:0211749 AUTH_NONE,
11750 OK,
11751 kServer,
11752 AUTH_ASYNC,
11753 ERR_INVALID_AUTH_CREDENTIALS,
11754 2,
11755 kNoSSL,
11756 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611757 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211758 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111759 {__LINE__,
11760 kProxy,
asankac93076192016-10-03 15:46:0211761 AUTH_SYNC,
11762 OK,
11763 kServer,
11764 AUTH_NONE,
11765 OK,
11766 2,
11767 kNoSSL,
11768 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511769 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111770 {__LINE__,
11771 kProxy,
asankac93076192016-10-03 15:46:0211772 AUTH_SYNC,
11773 ERR_INVALID_AUTH_CREDENTIALS,
11774 kServer,
11775 AUTH_NONE,
11776 OK,
11777 2,
11778 kNoSSL,
11779 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611780 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111781 {__LINE__,
11782 kProxy,
asankac93076192016-10-03 15:46:0211783 AUTH_ASYNC,
11784 OK,
11785 kServer,
11786 AUTH_NONE,
11787 OK,
11788 2,
11789 kNoSSL,
11790 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511791 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111792 {__LINE__,
11793 kProxy,
asankac93076192016-10-03 15:46:0211794 AUTH_ASYNC,
11795 ERR_INVALID_AUTH_CREDENTIALS,
11796 kServer,
11797 AUTH_NONE,
11798 OK,
11799 2,
11800 kNoSSL,
11801 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611802 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111803 {__LINE__,
11804 kProxy,
11805 AUTH_ASYNC,
11806 ERR_INVALID_AUTH_CREDENTIALS,
11807 kServer,
11808 AUTH_NONE,
11809 OK,
11810 3,
11811 kNoSSL,
11812 {TestRound(kGetProxy, kProxyChallenge, OK),
11813 TestRound(kGetProxy, kProxyChallenge, OK),
11814 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211815 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111816 {__LINE__,
11817 kProxy,
asankac93076192016-10-03 15:46:0211818 AUTH_SYNC,
11819 OK,
11820 kServer,
11821 AUTH_SYNC,
11822 OK,
11823 3,
11824 kNoSSL,
11825 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511826 TestRound(kGetProxyAuth, kServerChallenge, OK),
11827 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111828 {__LINE__,
11829 kProxy,
asankac93076192016-10-03 15:46:0211830 AUTH_SYNC,
11831 OK,
11832 kServer,
11833 AUTH_SYNC,
11834 ERR_INVALID_AUTH_CREDENTIALS,
11835 3,
11836 kNoSSL,
11837 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511838 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611839 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111840 {__LINE__,
11841 kProxy,
asankac93076192016-10-03 15:46:0211842 AUTH_ASYNC,
11843 OK,
11844 kServer,
11845 AUTH_SYNC,
11846 OK,
11847 3,
11848 kNoSSL,
11849 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511850 TestRound(kGetProxyAuth, kServerChallenge, OK),
11851 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111852 {__LINE__,
11853 kProxy,
asankac93076192016-10-03 15:46:0211854 AUTH_ASYNC,
11855 OK,
11856 kServer,
11857 AUTH_SYNC,
11858 ERR_INVALID_AUTH_CREDENTIALS,
11859 3,
11860 kNoSSL,
11861 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511862 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611863 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111864 {__LINE__,
11865 kProxy,
asankac93076192016-10-03 15:46:0211866 AUTH_SYNC,
11867 OK,
11868 kServer,
11869 AUTH_ASYNC,
11870 OK,
11871 3,
11872 kNoSSL,
11873 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511874 TestRound(kGetProxyAuth, kServerChallenge, OK),
11875 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111876 {__LINE__,
11877 kProxy,
11878 AUTH_SYNC,
11879 ERR_INVALID_AUTH_CREDENTIALS,
11880 kServer,
11881 AUTH_ASYNC,
11882 OK,
11883 4,
11884 kNoSSL,
11885 {TestRound(kGetProxy, kProxyChallenge, OK),
11886 TestRound(kGetProxy, kProxyChallenge, OK),
11887 TestRound(kGetProxyAuth, kServerChallenge, OK),
11888 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11889 {__LINE__,
11890 kProxy,
asankac93076192016-10-03 15:46:0211891 AUTH_SYNC,
11892 OK,
11893 kServer,
11894 AUTH_ASYNC,
11895 ERR_INVALID_AUTH_CREDENTIALS,
11896 3,
11897 kNoSSL,
11898 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511899 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611900 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111901 {__LINE__,
11902 kProxy,
asankac93076192016-10-03 15:46:0211903 AUTH_ASYNC,
11904 OK,
11905 kServer,
11906 AUTH_ASYNC,
11907 OK,
11908 3,
11909 kNoSSL,
11910 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511911 TestRound(kGetProxyAuth, kServerChallenge, OK),
11912 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111913 {__LINE__,
11914 kProxy,
asankac93076192016-10-03 15:46:0211915 AUTH_ASYNC,
11916 OK,
11917 kServer,
11918 AUTH_ASYNC,
11919 ERR_INVALID_AUTH_CREDENTIALS,
11920 3,
11921 kNoSSL,
11922 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511923 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611924 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111925 {__LINE__,
11926 kProxy,
11927 AUTH_ASYNC,
11928 ERR_INVALID_AUTH_CREDENTIALS,
11929 kServer,
11930 AUTH_ASYNC,
11931 ERR_INVALID_AUTH_CREDENTIALS,
11932 4,
11933 kNoSSL,
11934 {TestRound(kGetProxy, kProxyChallenge, OK),
11935 TestRound(kGetProxy, kProxyChallenge, OK),
11936 TestRound(kGetProxyAuth, kServerChallenge, OK),
11937 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211938 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111939 {__LINE__,
11940 nullptr,
asankac93076192016-10-03 15:46:0211941 AUTH_NONE,
11942 OK,
11943 kSecureServer,
11944 AUTH_NONE,
11945 OK,
11946 1,
11947 0,
11948 {TestRound(kGet, kSuccess, OK)}},
11949 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111950 {__LINE__,
11951 nullptr,
asankac93076192016-10-03 15:46:0211952 AUTH_NONE,
11953 OK,
11954 kSecureServer,
11955 AUTH_SYNC,
11956 OK,
11957 2,
11958 0,
11959 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511960 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111961 {__LINE__,
11962 nullptr,
asankac93076192016-10-03 15:46:0211963 AUTH_NONE,
11964 OK,
11965 kSecureServer,
11966 AUTH_SYNC,
11967 ERR_INVALID_AUTH_CREDENTIALS,
11968 2,
11969 0,
asankae2257db2016-10-11 22:03:1611970 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111971 {__LINE__,
11972 nullptr,
asankac93076192016-10-03 15:46:0211973 AUTH_NONE,
11974 OK,
11975 kSecureServer,
11976 AUTH_ASYNC,
11977 OK,
11978 2,
11979 0,
11980 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511981 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111982 {__LINE__,
11983 nullptr,
asankac93076192016-10-03 15:46:0211984 AUTH_NONE,
11985 OK,
11986 kSecureServer,
11987 AUTH_ASYNC,
11988 ERR_INVALID_AUTH_CREDENTIALS,
11989 2,
11990 0,
asankae2257db2016-10-11 22:03:1611991 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211992 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111993 {__LINE__,
11994 kProxy,
asankac93076192016-10-03 15:46:0211995 AUTH_NONE,
11996 OK,
11997 kSecureServer,
11998 AUTH_NONE,
11999 OK,
12000 1,
12001 0,
12002 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12003 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112004 {__LINE__,
12005 kProxy,
asankac93076192016-10-03 15:46:0212006 AUTH_NONE,
12007 OK,
12008 kSecureServer,
12009 AUTH_SYNC,
12010 OK,
12011 2,
12012 0,
12013 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512014 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112015 {__LINE__,
12016 kProxy,
asankac93076192016-10-03 15:46:0212017 AUTH_NONE,
12018 OK,
12019 kSecureServer,
12020 AUTH_SYNC,
12021 ERR_INVALID_AUTH_CREDENTIALS,
12022 2,
12023 0,
12024 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612025 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112026 {__LINE__,
12027 kProxy,
asankac93076192016-10-03 15:46:0212028 AUTH_NONE,
12029 OK,
12030 kSecureServer,
12031 AUTH_ASYNC,
12032 OK,
12033 2,
12034 0,
12035 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512036 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112037 {__LINE__,
12038 kProxy,
asankac93076192016-10-03 15:46:0212039 AUTH_NONE,
12040 OK,
12041 kSecureServer,
12042 AUTH_ASYNC,
12043 ERR_INVALID_AUTH_CREDENTIALS,
12044 2,
12045 0,
12046 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612047 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212048 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112049 {__LINE__,
12050 kProxy,
asankac93076192016-10-03 15:46:0212051 AUTH_SYNC,
12052 OK,
12053 kSecureServer,
12054 AUTH_NONE,
12055 OK,
12056 2,
12057 1,
12058 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512059 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112060 {__LINE__,
12061 kProxy,
asankac93076192016-10-03 15:46:0212062 AUTH_SYNC,
12063 ERR_INVALID_AUTH_CREDENTIALS,
12064 kSecureServer,
12065 AUTH_NONE,
12066 OK,
12067 2,
12068 kNoSSL,
12069 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612070 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112071 {__LINE__,
12072 kProxy,
asankae2257db2016-10-11 22:03:1612073 AUTH_SYNC,
12074 ERR_UNSUPPORTED_AUTH_SCHEME,
12075 kSecureServer,
12076 AUTH_NONE,
12077 OK,
12078 2,
12079 kNoSSL,
12080 {TestRound(kConnect, kProxyChallenge, OK),
12081 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112082 {__LINE__,
12083 kProxy,
asankae2257db2016-10-11 22:03:1612084 AUTH_SYNC,
12085 ERR_UNEXPECTED,
12086 kSecureServer,
12087 AUTH_NONE,
12088 OK,
12089 2,
12090 kNoSSL,
12091 {TestRound(kConnect, kProxyChallenge, OK),
12092 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112093 {__LINE__,
12094 kProxy,
asankac93076192016-10-03 15:46:0212095 AUTH_ASYNC,
12096 OK,
12097 kSecureServer,
12098 AUTH_NONE,
12099 OK,
12100 2,
12101 1,
12102 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512103 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112104 {__LINE__,
12105 kProxy,
asankac93076192016-10-03 15:46:0212106 AUTH_ASYNC,
12107 ERR_INVALID_AUTH_CREDENTIALS,
12108 kSecureServer,
12109 AUTH_NONE,
12110 OK,
12111 2,
12112 kNoSSL,
12113 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612114 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212115 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112116 {__LINE__,
12117 kProxy,
asankac93076192016-10-03 15:46:0212118 AUTH_SYNC,
12119 OK,
12120 kSecureServer,
12121 AUTH_SYNC,
12122 OK,
12123 3,
12124 1,
12125 {TestRound(kConnect, kProxyChallenge, OK),
12126 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12127 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512128 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112129 {__LINE__,
12130 kProxy,
asankac93076192016-10-03 15:46:0212131 AUTH_SYNC,
12132 OK,
12133 kSecureServer,
12134 AUTH_SYNC,
12135 ERR_INVALID_AUTH_CREDENTIALS,
12136 3,
12137 1,
12138 {TestRound(kConnect, kProxyChallenge, OK),
12139 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12140 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612141 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112142 {__LINE__,
12143 kProxy,
asankac93076192016-10-03 15:46:0212144 AUTH_ASYNC,
12145 OK,
12146 kSecureServer,
12147 AUTH_SYNC,
12148 OK,
12149 3,
12150 1,
12151 {TestRound(kConnect, kProxyChallenge, OK),
12152 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12153 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512154 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112155 {__LINE__,
12156 kProxy,
asankac93076192016-10-03 15:46:0212157 AUTH_ASYNC,
12158 OK,
12159 kSecureServer,
12160 AUTH_SYNC,
12161 ERR_INVALID_AUTH_CREDENTIALS,
12162 3,
12163 1,
12164 {TestRound(kConnect, kProxyChallenge, OK),
12165 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12166 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612167 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112168 {__LINE__,
12169 kProxy,
asankac93076192016-10-03 15:46:0212170 AUTH_SYNC,
12171 OK,
12172 kSecureServer,
12173 AUTH_ASYNC,
12174 OK,
12175 3,
12176 1,
12177 {TestRound(kConnect, kProxyChallenge, OK),
12178 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12179 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512180 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112181 {__LINE__,
12182 kProxy,
asankac93076192016-10-03 15:46:0212183 AUTH_SYNC,
12184 OK,
12185 kSecureServer,
12186 AUTH_ASYNC,
12187 ERR_INVALID_AUTH_CREDENTIALS,
12188 3,
12189 1,
12190 {TestRound(kConnect, kProxyChallenge, OK),
12191 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12192 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612193 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112194 {__LINE__,
12195 kProxy,
asankac93076192016-10-03 15:46:0212196 AUTH_ASYNC,
12197 OK,
12198 kSecureServer,
12199 AUTH_ASYNC,
12200 OK,
12201 3,
12202 1,
12203 {TestRound(kConnect, kProxyChallenge, OK),
12204 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12205 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512206 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112207 {__LINE__,
12208 kProxy,
asankac93076192016-10-03 15:46:0212209 AUTH_ASYNC,
12210 OK,
12211 kSecureServer,
12212 AUTH_ASYNC,
12213 ERR_INVALID_AUTH_CREDENTIALS,
12214 3,
12215 1,
12216 {TestRound(kConnect, kProxyChallenge, OK),
12217 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12218 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612219 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112220 {__LINE__,
12221 kProxy,
12222 AUTH_ASYNC,
12223 ERR_INVALID_AUTH_CREDENTIALS,
12224 kSecureServer,
12225 AUTH_ASYNC,
12226 ERR_INVALID_AUTH_CREDENTIALS,
12227 4,
12228 2,
12229 {TestRound(kConnect, kProxyChallenge, OK),
12230 TestRound(kConnect, kProxyChallenge, OK),
12231 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12232 &kServerChallenge),
12233 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512234 };
12235
asanka463ca4262016-11-16 02:34:3112236 for (const auto& test_config : test_configs) {
12237 SCOPED_TRACE(::testing::Message() << "Test config at "
12238 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812239 HttpAuthHandlerMock::Factory* auth_factory(
12240 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712241 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912242 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612243
12244 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512245 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112246 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812247 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12248 std::string auth_challenge = "Mock realm=proxy";
12249 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412250 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12251 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812252 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012253 empty_ssl_info, origin,
12254 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812255 auth_handler->SetGenerateExpectation(
12256 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112257 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812258 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12259 }
[email protected]044de0642010-06-17 10:42:1512260 }
12261 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012262 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512263 std::string auth_challenge = "Mock realm=server";
12264 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412265 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12266 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512267 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012268 empty_ssl_info, origin,
12269 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512270 auth_handler->SetGenerateExpectation(
12271 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112272 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812273 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612274
12275 // The second handler always succeeds. It should only be used where there
12276 // are multiple auth sessions for server auth in the same network
12277 // transaction using the same auth scheme.
12278 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12279 base::MakeUnique<HttpAuthHandlerMock>();
12280 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12281 empty_ssl_info, origin,
12282 NetLogWithSource());
12283 second_handler->SetGenerateExpectation(true, OK);
12284 auth_factory->AddMockHandler(second_handler.release(),
12285 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512286 }
12287 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312288 session_deps_.proxy_service =
12289 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512290 } else {
rdsmith82957ad2015-09-16 19:42:0312291 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512292 }
12293
12294 HttpRequestInfo request;
12295 request.method = "GET";
12296 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512297
danakj1fd259a02016-04-16 03:17:0912298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512299
rchcb68dc62015-05-21 04:45:3612300 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12301
12302 std::vector<std::vector<MockRead>> mock_reads(1);
12303 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512304 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212305 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512306 const TestRound& read_write_round = test_config.rounds[round];
12307
12308 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612309 mock_reads.back().push_back(read_write_round.read);
12310 mock_writes.back().push_back(read_write_round.write);
12311
12312 // kProxyChallenge uses Proxy-Connection: close which means that the
12313 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412314 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612315 mock_reads.push_back(std::vector<MockRead>());
12316 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512317 }
12318
rchcb68dc62015-05-21 04:45:3612319 if (read_write_round.extra_read) {
12320 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512321 }
rchcb68dc62015-05-21 04:45:3612322 if (read_write_round.extra_write) {
12323 mock_writes.back().push_back(*read_write_round.extra_write);
12324 }
[email protected]044de0642010-06-17 10:42:1512325
12326 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512327 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712328 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512329 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612330 }
[email protected]044de0642010-06-17 10:42:1512331
danakj1fd259a02016-04-16 03:17:0912332 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612333 for (size_t i = 0; i < mock_reads.size(); ++i) {
bnc87dcefc2017-05-25 12:47:5812334 data_providers.push_back(base::MakeUnique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412335 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812336 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612337 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212338 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612339 }
12340
mmenkecc2298e2015-12-07 18:20:1812341 // Transaction must be created after DataProviders, so it's destroyed before
12342 // they are as well.
12343 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12344
rchcb68dc62015-05-21 04:45:3612345 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212346 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612347 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512348 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112349 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512350 int rv;
12351 if (round == 0) {
tfarina42834112016-09-22 13:38:2012352 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512353 } else {
[email protected]49639fa2011-12-20 23:22:4112354 rv = trans.RestartWithAuth(
12355 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512356 }
12357 if (rv == ERR_IO_PENDING)
12358 rv = callback.WaitForResult();
12359
12360 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612361 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012362 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512363 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512364 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12365 continue;
12366 }
12367 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212368 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512369 } else {
wezca1070932016-05-26 20:30:5212370 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612371 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512372 }
12373 }
[email protected]e5ae96a2010-04-14 20:12:4512374 }
12375}
12376
bncd16676a2016-07-20 16:23:0112377TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412378 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412379 HttpAuthHandlerMock::Factory* auth_factory(
12380 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712381 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312382 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712383 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12384 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412385
12386 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12387 auth_handler->set_connection_based(true);
12388 std::string auth_challenge = "Mock realm=server";
12389 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412390 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12391 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912392 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412393 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012394 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812395 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412396
[email protected]c871bce92010-07-15 21:51:1412397 int rv = OK;
12398 const HttpResponseInfo* response = NULL;
12399 HttpRequestInfo request;
12400 request.method = "GET";
12401 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712402
danakj1fd259a02016-04-16 03:17:0912403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012404
12405 // Use a TCP Socket Pool with only one connection per group. This is used
12406 // to validate that the TCP socket is not released to the pool between
12407 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212408 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812409 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012410 50, // Max sockets for pool
12411 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112412 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12413 NULL, session_deps_.net_log);
bnc87dcefc2017-05-25 12:47:5812414 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212415 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812416 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012417
bnc691fda62016-08-12 00:43:1612418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112419 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412420
12421 const MockWrite kGet(
12422 "GET / HTTP/1.1\r\n"
12423 "Host: www.example.com\r\n"
12424 "Connection: keep-alive\r\n\r\n");
12425 const MockWrite kGetAuth(
12426 "GET / HTTP/1.1\r\n"
12427 "Host: www.example.com\r\n"
12428 "Connection: keep-alive\r\n"
12429 "Authorization: auth_token\r\n\r\n");
12430
12431 const MockRead kServerChallenge(
12432 "HTTP/1.1 401 Unauthorized\r\n"
12433 "WWW-Authenticate: Mock realm=server\r\n"
12434 "Content-Type: text/html; charset=iso-8859-1\r\n"
12435 "Content-Length: 14\r\n\r\n"
12436 "Unauthorized\r\n");
12437 const MockRead kSuccess(
12438 "HTTP/1.1 200 OK\r\n"
12439 "Content-Type: text/html; charset=iso-8859-1\r\n"
12440 "Content-Length: 3\r\n\r\n"
12441 "Yes");
12442
12443 MockWrite writes[] = {
12444 // First round
12445 kGet,
12446 // Second round
12447 kGetAuth,
12448 // Third round
12449 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012450 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012451 kGetAuth,
12452 // Competing request
12453 kGet,
[email protected]c871bce92010-07-15 21:51:1412454 };
12455 MockRead reads[] = {
12456 // First round
12457 kServerChallenge,
12458 // Second round
12459 kServerChallenge,
12460 // Third round
[email protected]eca50e122010-09-11 14:03:3012461 kServerChallenge,
12462 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412463 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012464 // Competing response
12465 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412466 };
12467 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12468 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712469 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412470
thestig9d3bb0c2015-01-24 00:49:5112471 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012472
12473 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412474 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012475 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412476 if (rv == ERR_IO_PENDING)
12477 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112478 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612479 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212480 ASSERT_TRUE(response);
12481 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812482 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112483 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12484 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412485
[email protected]7ef4cbbb2011-02-06 11:19:1012486 // In between rounds, another request comes in for the same domain.
12487 // It should not be able to grab the TCP socket that trans has already
12488 // claimed.
bnc691fda62016-08-12 00:43:1612489 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112490 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012491 rv = trans_compete.Start(&request, callback_compete.callback(),
12492 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012494 // callback_compete.WaitForResult at this point would stall forever,
12495 // since the HttpNetworkTransaction does not release the request back to
12496 // the pool until after authentication completes.
12497
12498 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412499 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612500 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412501 if (rv == ERR_IO_PENDING)
12502 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112503 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612504 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212505 ASSERT_TRUE(response);
12506 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812507 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112508 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12509 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412510
[email protected]7ef4cbbb2011-02-06 11:19:1012511 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412512 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612513 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412514 if (rv == ERR_IO_PENDING)
12515 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112516 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612517 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212518 ASSERT_TRUE(response);
12519 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812520 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112521 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12522 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012523
[email protected]7ef4cbbb2011-02-06 11:19:1012524 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012525 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612526 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012527 if (rv == ERR_IO_PENDING)
12528 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112529 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612530 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212531 ASSERT_TRUE(response);
12532 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812533 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012534
asanka463ca4262016-11-16 02:34:3112535 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12536 // auth handler should transition to a DONE state in concert with the remote
12537 // server. But that's not something we can test here with a mock handler.
12538 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12539 auth_handler->state());
12540
[email protected]7ef4cbbb2011-02-06 11:19:1012541 // Read the body since the fourth round was successful. This will also
12542 // release the socket back to the pool.
12543 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612544 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012545 if (rv == ERR_IO_PENDING)
12546 rv = callback.WaitForResult();
12547 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612548 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012549 EXPECT_EQ(0, rv);
12550 // There are still 0 idle sockets, since the trans_compete transaction
12551 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812552 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012553
12554 // The competing request can now finish. Wait for the headers and then
12555 // read the body.
12556 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112557 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612558 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012559 if (rv == ERR_IO_PENDING)
12560 rv = callback.WaitForResult();
12561 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612562 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012563 EXPECT_EQ(0, rv);
12564
12565 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812566 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412567}
12568
[email protected]65041fa2010-05-21 06:56:5312569// This tests the case that a request is issued via http instead of spdy after
12570// npn is negotiated.
bncd16676a2016-07-20 16:23:0112571TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312572 HttpRequestInfo request;
12573 request.method = "GET";
bncce36dca22015-04-21 22:11:2312574 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312575
12576 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312577 MockWrite(
12578 "GET / HTTP/1.1\r\n"
12579 "Host: www.example.org\r\n"
12580 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312581 };
12582
12583 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212584 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312585 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212586 MockRead("\r\n"),
12587 MockRead("hello world"),
12588 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312589 };
12590
[email protected]8ddf8322012-02-23 18:08:0612591 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612592 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312593
[email protected]bb88e1d32013-05-03 23:11:0712594 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312595
12596 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12597 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712598 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312599
[email protected]49639fa2011-12-20 23:22:4112600 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312601
danakj1fd259a02016-04-16 03:17:0912602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312604
tfarina42834112016-09-22 13:38:2012605 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312606
robpercival214763f2016-07-01 23:27:0112607 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12608 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312609
bnc691fda62016-08-12 00:43:1612610 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212611 ASSERT_TRUE(response);
12612 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312613 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12614
12615 std::string response_data;
bnc691fda62016-08-12 00:43:1612616 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312617 EXPECT_EQ("hello world", response_data);
12618
12619 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212620 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312621}
[email protected]26ef6582010-06-24 02:30:4712622
bnc55ff9da2015-08-19 18:42:3512623// Simulate the SSL handshake completing with an NPN negotiation followed by an
12624// immediate server closing of the socket.
12625// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112626TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712627 HttpRequestInfo request;
12628 request.method = "GET";
bncce36dca22015-04-21 22:11:2312629 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712630
[email protected]8ddf8322012-02-23 18:08:0612631 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612632 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712634
bncdf80d44fd2016-07-15 20:27:4112635 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912636 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112637 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712638
12639 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612640 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712641 };
12642
rch8e6c6c42015-05-01 14:05:1312643 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12644 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712645 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712646
[email protected]49639fa2011-12-20 23:22:4112647 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712648
danakj1fd259a02016-04-16 03:17:0912649 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612650 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712651
tfarina42834112016-09-22 13:38:2012652 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12654 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712655}
[email protected]65d34382010-07-01 18:12:2612656
[email protected]795cbf82013-07-22 09:37:2712657// A subclass of HttpAuthHandlerMock that records the request URL when
12658// it gets it. This is needed since the auth handler may get destroyed
12659// before we get a chance to query it.
12660class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12661 public:
12662 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12663
dchengb03027d2014-10-21 12:00:2012664 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712665
12666 protected:
dchengb03027d2014-10-21 12:00:2012667 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12668 const HttpRequestInfo* request,
12669 const CompletionCallback& callback,
12670 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712671 *url_ = request->url;
12672 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12673 credentials, request, callback, auth_token);
12674 }
12675
12676 private:
12677 GURL* url_;
12678};
12679
[email protected]8e6441ca2010-08-19 05:56:3812680// Test that if we cancel the transaction as the connection is completing, that
12681// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112682TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812683 // Setup everything about the connection to complete synchronously, so that
12684 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12685 // for is the callback from the HttpStreamRequest.
12686 // Then cancel the transaction.
12687 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612688 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812689 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612690 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12691 MockRead(SYNCHRONOUS, "hello world"),
12692 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812693 };
12694
[email protected]8e6441ca2010-08-19 05:56:3812695 HttpRequestInfo request;
12696 request.method = "GET";
bncce36dca22015-04-21 22:11:2312697 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812698
[email protected]bb88e1d32013-05-03 23:11:0712699 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812701 auto trans =
12702 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2712703
[email protected]8e6441ca2010-08-19 05:56:3812704 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12705 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712706 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812707
[email protected]49639fa2011-12-20 23:22:4112708 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812709
vishal.b62985ca92015-04-17 08:45:5112710 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112711 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812713 trans.reset(); // Cancel the transaction here.
12714
fdoray92e35a72016-06-10 15:54:5512715 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012716}
12717
[email protected]ecab6e052014-05-16 14:58:1212718// Test that if a transaction is cancelled after receiving the headers, the
12719// stream is drained properly and added back to the socket pool. The main
12720// purpose of this test is to make sure that an HttpStreamParser can be read
12721// from after the HttpNetworkTransaction and the objects it owns have been
12722// deleted.
12723// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112724TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212725 MockRead data_reads[] = {
12726 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12727 MockRead(ASYNC, "Content-Length: 2\r\n"),
12728 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12729 MockRead(ASYNC, "1"),
12730 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12731 // HttpNetworkTransaction has been deleted.
12732 MockRead(ASYNC, "2"),
12733 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12734 };
12735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12736 session_deps_.socket_factory->AddSocketDataProvider(&data);
12737
danakj1fd259a02016-04-16 03:17:0912738 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212739
12740 {
12741 HttpRequestInfo request;
12742 request.method = "GET";
bncce36dca22015-04-21 22:11:2312743 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212744
dcheng48459ac22014-08-26 00:46:4112745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212746 TestCompletionCallback callback;
12747
tfarina42834112016-09-22 13:38:2012748 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212750 callback.WaitForResult();
12751
12752 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212753 ASSERT_TRUE(response);
12754 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212755 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12756
12757 // The transaction and HttpRequestInfo are deleted.
12758 }
12759
12760 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512761 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212762
12763 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112764 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212765}
12766
[email protected]76a505b2010-08-25 06:23:0012767// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112768TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312769 session_deps_.proxy_service =
12770 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112771 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712772 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012774
[email protected]76a505b2010-08-25 06:23:0012775 HttpRequestInfo request;
12776 request.method = "GET";
bncce36dca22015-04-21 22:11:2312777 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012778
12779 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312780 MockWrite(
12781 "GET http://www.example.org/ HTTP/1.1\r\n"
12782 "Host: www.example.org\r\n"
12783 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012784 };
12785
12786 MockRead data_reads1[] = {
12787 MockRead("HTTP/1.1 200 OK\r\n"),
12788 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12789 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612790 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012791 };
12792
12793 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12794 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712795 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012796
[email protected]49639fa2011-12-20 23:22:4112797 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012798
bnc691fda62016-08-12 00:43:1612799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912800 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612801 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912802 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12803 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012804
bnc691fda62016-08-12 00:43:1612805 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012807
12808 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112809 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012810
bnc691fda62016-08-12 00:43:1612811 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212812 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012813
12814 EXPECT_TRUE(response->headers->IsKeepAlive());
12815 EXPECT_EQ(200, response->headers->response_code());
12816 EXPECT_EQ(100, response->headers->GetContentLength());
12817 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712818 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12819 HostPortPair::FromString("myproxy:70")),
12820 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912821 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12822 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12823 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012824 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012825
12826 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612827 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012828 TestLoadTimingNotReusedWithPac(load_timing_info,
12829 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012830}
12831
12832// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112833TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312834 session_deps_.proxy_service =
12835 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112836 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712837 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012839
[email protected]76a505b2010-08-25 06:23:0012840 HttpRequestInfo request;
12841 request.method = "GET";
bncce36dca22015-04-21 22:11:2312842 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012843
12844 // Since we have proxy, should try to establish tunnel.
12845 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712846 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12847 "Host: www.example.org:443\r\n"
12848 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012849
rsleevidb16bb02015-11-12 23:47:1712850 MockWrite("GET / HTTP/1.1\r\n"
12851 "Host: www.example.org\r\n"
12852 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012853 };
12854
12855 MockRead data_reads1[] = {
12856 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12857
12858 MockRead("HTTP/1.1 200 OK\r\n"),
12859 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12860 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612861 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012862 };
12863
12864 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12865 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712866 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612867 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712868 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012869
[email protected]49639fa2011-12-20 23:22:4112870 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012871
bnc691fda62016-08-12 00:43:1612872 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912873 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612874 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912875 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12876 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012877
bnc691fda62016-08-12 00:43:1612878 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112879 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012880
12881 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112882 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612883 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012884 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012885 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012886 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12887 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012888 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012889 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012890 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12891 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012892
bnc691fda62016-08-12 00:43:1612893 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212894 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012895
12896 EXPECT_TRUE(response->headers->IsKeepAlive());
12897 EXPECT_EQ(200, response->headers->response_code());
12898 EXPECT_EQ(100, response->headers->GetContentLength());
12899 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12900 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712901 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12902 HostPortPair::FromString("myproxy:70")),
12903 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912904 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12905 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12906 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012907
12908 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612909 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012910 TestLoadTimingNotReusedWithPac(load_timing_info,
12911 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012912}
12913
rsleevidb16bb02015-11-12 23:47:1712914// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12915// literal host.
bncd16676a2016-07-20 16:23:0112916TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712917 session_deps_.proxy_service =
12918 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12919 BoundTestNetLog log;
12920 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712922
12923 HttpRequestInfo request;
12924 request.method = "GET";
12925 request.url = GURL("https://[::1]:443/");
12926
12927 // Since we have proxy, should try to establish tunnel.
12928 MockWrite data_writes1[] = {
12929 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12930 "Host: [::1]:443\r\n"
12931 "Proxy-Connection: keep-alive\r\n\r\n"),
12932
12933 MockWrite("GET / HTTP/1.1\r\n"
12934 "Host: [::1]\r\n"
12935 "Connection: keep-alive\r\n\r\n"),
12936 };
12937
12938 MockRead data_reads1[] = {
12939 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12940
12941 MockRead("HTTP/1.1 200 OK\r\n"),
12942 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12943 MockRead("Content-Length: 100\r\n\r\n"),
12944 MockRead(SYNCHRONOUS, OK),
12945 };
12946
12947 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12948 data_writes1, arraysize(data_writes1));
12949 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12950 SSLSocketDataProvider ssl(ASYNC, OK);
12951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12952
12953 TestCompletionCallback callback1;
12954
bnc691fda62016-08-12 00:43:1612955 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712956
bnc691fda62016-08-12 00:43:1612957 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712959
12960 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112961 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712962 TestNetLogEntry::List entries;
12963 log.GetEntries(&entries);
12964 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012965 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12966 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712967 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012968 entries, pos,
12969 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12970 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712971
bnc691fda62016-08-12 00:43:1612972 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212973 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712974
12975 EXPECT_TRUE(response->headers->IsKeepAlive());
12976 EXPECT_EQ(200, response->headers->response_code());
12977 EXPECT_EQ(100, response->headers->GetContentLength());
12978 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12979 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712980 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12981 HostPortPair::FromString("myproxy:70")),
12982 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712983
12984 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612985 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712986 TestLoadTimingNotReusedWithPac(load_timing_info,
12987 CONNECT_TIMING_HAS_SSL_TIMES);
12988}
12989
[email protected]76a505b2010-08-25 06:23:0012990// Test a basic HTTPS GET request through a proxy, but the server hangs up
12991// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112992TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312993 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112994 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712995 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912996 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012997
[email protected]76a505b2010-08-25 06:23:0012998 HttpRequestInfo request;
12999 request.method = "GET";
bncce36dca22015-04-21 22:11:2313000 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013001
13002 // Since we have proxy, should try to establish tunnel.
13003 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713004 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13005 "Host: www.example.org:443\r\n"
13006 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013007
rsleevidb16bb02015-11-12 23:47:1713008 MockWrite("GET / HTTP/1.1\r\n"
13009 "Host: www.example.org\r\n"
13010 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013011 };
13012
13013 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613014 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013015 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613016 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013017 };
13018
13019 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13020 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713021 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613022 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713023 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013024
[email protected]49639fa2011-12-20 23:22:4113025 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013026
bnc691fda62016-08-12 00:43:1613027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013028
bnc691fda62016-08-12 00:43:1613029 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013031
13032 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113033 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613034 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013035 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013036 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013037 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13038 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013039 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013040 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013041 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13042 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013043}
13044
[email protected]749eefa82010-09-13 22:14:0313045// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113046TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113047 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913048 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113049 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313050
bnc42331402016-07-25 13:36:1513051 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113052 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313053 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113054 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313055 };
13056
rch8e6c6c42015-05-01 14:05:1313057 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13058 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713059 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313060
[email protected]8ddf8322012-02-23 18:08:0613061 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613062 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313064
danakj1fd259a02016-04-16 03:17:0913065 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313066
13067 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313068 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013069 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313070 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713071 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513072 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313073
13074 HttpRequestInfo request;
13075 request.method = "GET";
bncce36dca22015-04-21 22:11:2313076 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313077
13078 // This is the important line that marks this as a preconnect.
13079 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13080
bnc691fda62016-08-12 00:43:1613081 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313082
[email protected]41d64e82013-07-03 22:44:2613083 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013084 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13086 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313087}
13088
[email protected]73b8dd222010-11-11 19:55:2413089// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613090// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213091void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713092 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913093 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713094 request_info.url = GURL("https://www.example.com/");
13095 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913096 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713097
[email protected]8ddf8322012-02-23 18:08:0613098 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913099 MockWrite data_writes[] = {
13100 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413101 };
ttuttle859dc7a2015-04-23 19:42:2913102 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713103 session_deps_.socket_factory->AddSocketDataProvider(&data);
13104 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413105
danakj1fd259a02016-04-16 03:17:0913106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413108
[email protected]49639fa2011-12-20 23:22:4113109 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013110 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913111 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413112 rv = callback.WaitForResult();
13113 ASSERT_EQ(error, rv);
13114}
13115
bncd16676a2016-07-20 16:23:0113116TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413117 // Just check a grab bag of cert errors.
13118 static const int kErrors[] = {
13119 ERR_CERT_COMMON_NAME_INVALID,
13120 ERR_CERT_AUTHORITY_INVALID,
13121 ERR_CERT_DATE_INVALID,
13122 };
13123 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613124 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13125 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413126 }
13127}
13128
[email protected]bd0b6772011-01-11 19:59:3013129// Ensure that a client certificate is removed from the SSL client auth
13130// cache when:
13131// 1) No proxy is involved.
13132// 2) TLS False Start is disabled.
13133// 3) The initial TLS handshake requests a client certificate.
13134// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113135TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913136 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713137 request_info.url = GURL("https://www.example.com/");
13138 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913139 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713140
[email protected]bd0b6772011-01-11 19:59:3013141 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113142 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013143
13144 // [ssl_]data1 contains the data for the first SSL handshake. When a
13145 // CertificateRequest is received for the first time, the handshake will
13146 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913147 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013148 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713149 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913150 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713151 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013152
13153 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13154 // False Start is not being used, the result of the SSL handshake will be
13155 // returned as part of the SSLClientSocket::Connect() call. This test
13156 // matches the result of a server sending a handshake_failure alert,
13157 // rather than a Finished message, because it requires a client
13158 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913159 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013160 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713161 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913162 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713163 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013164
13165 // [ssl_]data3 contains the data for the third SSL handshake. When a
13166 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213167 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13168 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013169 // of the HttpNetworkTransaction. Because this test failure is due to
13170 // requiring a client certificate, this fallback handshake should also
13171 // fail.
ttuttle859dc7a2015-04-23 19:42:2913172 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013173 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913175 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713176 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013177
[email protected]80c75f682012-05-26 16:22:1713178 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13179 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213180 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13181 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713182 // of the HttpNetworkTransaction. Because this test failure is due to
13183 // requiring a client certificate, this fallback handshake should also
13184 // fail.
ttuttle859dc7a2015-04-23 19:42:2913185 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713186 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713187 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913188 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713189 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713190
danakj1fd259a02016-04-16 03:17:0913191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013193
[email protected]bd0b6772011-01-11 19:59:3013194 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113195 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013196 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113197 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013198
13199 // Complete the SSL handshake, which should abort due to requiring a
13200 // client certificate.
13201 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113202 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013203
13204 // Indicate that no certificate should be supplied. From the perspective
13205 // of SSLClientCertCache, NULL is just as meaningful as a real
13206 // certificate, so this is the same as supply a
13207 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613208 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113209 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013210
13211 // Ensure the certificate was added to the client auth cache before
13212 // allowing the connection to continue restarting.
13213 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413214 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113215 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413216 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213217 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013218
13219 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713220 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13221 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013222 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113223 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013224
13225 // Ensure that the client certificate is removed from the cache on a
13226 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113227 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413228 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013229}
13230
13231// Ensure that a client certificate is removed from the SSL client auth
13232// cache when:
13233// 1) No proxy is involved.
13234// 2) TLS False Start is enabled.
13235// 3) The initial TLS handshake requests a client certificate.
13236// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113237TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913238 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713239 request_info.url = GURL("https://www.example.com/");
13240 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913241 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713242
[email protected]bd0b6772011-01-11 19:59:3013243 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113244 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013245
13246 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13247 // return successfully after reading up to the peer's Certificate message.
13248 // This is to allow the caller to call SSLClientSocket::Write(), which can
13249 // enqueue application data to be sent in the same packet as the
13250 // ChangeCipherSpec and Finished messages.
13251 // The actual handshake will be finished when SSLClientSocket::Read() is
13252 // called, which expects to process the peer's ChangeCipherSpec and
13253 // Finished messages. If there was an error negotiating with the peer,
13254 // such as due to the peer requiring a client certificate when none was
13255 // supplied, the alert sent by the peer won't be processed until Read() is
13256 // called.
13257
13258 // Like the non-False Start case, when a client certificate is requested by
13259 // the peer, the handshake is aborted during the Connect() call.
13260 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913261 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013262 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713263 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913264 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713265 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013266
13267 // When a client certificate is supplied, Connect() will not be aborted
13268 // when the peer requests the certificate. Instead, the handshake will
13269 // artificially succeed, allowing the caller to write the HTTP request to
13270 // the socket. The handshake messages are not processed until Read() is
13271 // called, which then detects that the handshake was aborted, due to the
13272 // peer sending a handshake_failure because it requires a client
13273 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913274 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013275 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913277 MockRead data2_reads[] = {
13278 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013279 };
ttuttle859dc7a2015-04-23 19:42:2913280 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713281 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013282
13283 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713284 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13285 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913286 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013287 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913289 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713290 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013291
[email protected]80c75f682012-05-26 16:22:1713292 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13293 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913294 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713295 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913297 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713298 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713299
[email protected]7799de12013-05-30 05:52:5113300 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913301 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113302 ssl_data5.cert_request_info = cert_request.get();
13303 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913304 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113305 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13306
danakj1fd259a02016-04-16 03:17:0913307 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013309
[email protected]bd0b6772011-01-11 19:59:3013310 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113311 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013312 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113313 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013314
13315 // Complete the SSL handshake, which should abort due to requiring a
13316 // client certificate.
13317 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113318 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013319
13320 // Indicate that no certificate should be supplied. From the perspective
13321 // of SSLClientCertCache, NULL is just as meaningful as a real
13322 // certificate, so this is the same as supply a
13323 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613324 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113325 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013326
13327 // Ensure the certificate was added to the client auth cache before
13328 // allowing the connection to continue restarting.
13329 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413330 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113331 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413332 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213333 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013334
[email protected]bd0b6772011-01-11 19:59:3013335 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713336 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13337 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013338 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113339 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013340
13341 // Ensure that the client certificate is removed from the cache on a
13342 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113343 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413344 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013345}
13346
[email protected]8c405132011-01-11 22:03:1813347// Ensure that a client certificate is removed from the SSL client auth
13348// cache when:
13349// 1) An HTTPS proxy is involved.
13350// 3) The HTTPS proxy requests a client certificate.
13351// 4) The client supplies an invalid/unacceptable certificate for the
13352// proxy.
13353// The test is repeated twice, first for connecting to an HTTPS endpoint,
13354// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113355TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313356 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113357 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713358 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813359
13360 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113361 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813362
13363 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13364 // [ssl_]data[1-3]. Rather than represending the endpoint
13365 // (www.example.com:443), they represent failures with the HTTPS proxy
13366 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913367 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813368 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913370 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713371 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813372
ttuttle859dc7a2015-04-23 19:42:2913373 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813374 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713375 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913376 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713377 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813378
[email protected]80c75f682012-05-26 16:22:1713379 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13380#if 0
ttuttle859dc7a2015-04-23 19:42:2913381 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813382 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913384 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713385 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713386#endif
[email protected]8c405132011-01-11 22:03:1813387
ttuttle859dc7a2015-04-23 19:42:2913388 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813389 requests[0].url = GURL("https://www.example.com/");
13390 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913391 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813392
13393 requests[1].url = GURL("http://www.example.com/");
13394 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913395 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813396
13397 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713398 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813401
13402 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113403 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013404 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113405 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813406
13407 // Complete the SSL handshake, which should abort due to requiring a
13408 // client certificate.
13409 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113410 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813411
13412 // Indicate that no certificate should be supplied. From the perspective
13413 // of SSLClientCertCache, NULL is just as meaningful as a real
13414 // certificate, so this is the same as supply a
13415 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613416 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113417 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813418
13419 // Ensure the certificate was added to the client auth cache before
13420 // allowing the connection to continue restarting.
13421 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413422 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113423 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413424 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213425 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813426 // Ensure the certificate was NOT cached for the endpoint. This only
13427 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113428 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413429 HostPortPair("www.example.com", 443), &client_cert,
13430 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813431
13432 // Restart the handshake. This will consume ssl_data2, which fails, and
13433 // then consume ssl_data3, which should also fail. The result code is
13434 // checked against what ssl_data3 should return.
13435 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113436 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813437
13438 // Now that the new handshake has failed, ensure that the client
13439 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113440 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413441 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113442 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413443 HostPortPair("www.example.com", 443), &client_cert,
13444 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813445 }
13446}
13447
bncd16676a2016-07-20 16:23:0113448TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613449 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813450 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613452
bnc032658ba2016-09-26 18:17:1513453 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613454
bncdf80d44fd2016-07-15 20:27:4113455 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913456 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813457 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113458 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713459 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613460 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113461 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613462 };
bnc42331402016-07-25 13:36:1513463 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113464 SpdySerializedFrame host1_resp_body(
13465 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513466 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113467 SpdySerializedFrame host2_resp_body(
13468 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613469 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113470 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13471 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313472 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613473 };
13474
eroman36d84e54432016-03-17 03:23:0213475 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213476 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313477 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13478 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713479 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613480
[email protected]aa22b242011-11-16 18:58:2913481 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613482 HttpRequestInfo request1;
13483 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313484 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613485 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013486 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613487
tfarina42834112016-09-22 13:38:2013488 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13490 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613491
13492 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213493 ASSERT_TRUE(response);
13494 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213495 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613496
13497 std::string response_data;
robpercival214763f2016-07-01 23:27:0113498 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613499 EXPECT_EQ("hello!", response_data);
13500
bnca4d611d2016-09-22 19:55:3713501 // Preload mail.example.com into HostCache.
13502 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013503 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613504 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013505 std::unique_ptr<HostResolver::Request> request;
13506 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13507 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013508 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113509 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713510 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113511 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613512
13513 HttpRequestInfo request2;
13514 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713515 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613516 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013517 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613518
tfarina42834112016-09-22 13:38:2013519 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113520 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13521 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613522
13523 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213524 ASSERT_TRUE(response);
13525 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213526 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613527 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213528 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113529 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613530 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613531}
13532
bncd16676a2016-07-20 16:23:0113533TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213534 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813535 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913536 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213537
bnc032658ba2016-09-26 18:17:1513538 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213539
bncdf80d44fd2016-07-15 20:27:4113540 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913541 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813542 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113543 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713544 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213545 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113546 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213547 };
bnc42331402016-07-25 13:36:1513548 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113549 SpdySerializedFrame host1_resp_body(
13550 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513551 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113552 SpdySerializedFrame host2_resp_body(
13553 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213554 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113555 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13556 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313557 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213558 };
13559
eroman36d84e54432016-03-17 03:23:0213560 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213561 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313562 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13563 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713564 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213565
13566 TestCompletionCallback callback;
13567 HttpRequestInfo request1;
13568 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313569 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213570 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013571 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213572
tfarina42834112016-09-22 13:38:2013573 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13575 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213576
13577 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213578 ASSERT_TRUE(response);
13579 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213580 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213581
13582 std::string response_data;
robpercival214763f2016-07-01 23:27:0113583 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213584 EXPECT_EQ("hello!", response_data);
13585
13586 HttpRequestInfo request2;
13587 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713588 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213589 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013590 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213591
tfarina42834112016-09-22 13:38:2013592 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113593 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13594 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213595
13596 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213597 ASSERT_TRUE(response);
13598 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213599 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213600 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213601 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113602 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213603 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213604}
13605
bnc8016c1f2017-03-31 02:11:2913606// Regression test for https://crbug.com/546991.
13607// The server might not be able to serve an IP pooled request, and might send a
13608// 421 Misdirected Request response status to indicate this.
13609// HttpNetworkTransaction should reset the request and retry without IP pooling.
13610TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13611 // Two hosts resolve to the same IP address.
13612 const std::string ip_addr = "1.2.3.4";
13613 IPAddress ip;
13614 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13615 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13616
bnc87dcefc2017-05-25 12:47:5813617 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913618 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13619 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13620
13621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13622
13623 // Two requests on the first connection.
13624 SpdySerializedFrame req1(
13625 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13626 spdy_util_.UpdateWithStreamDestruction(1);
13627 SpdySerializedFrame req2(
13628 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13629 SpdySerializedFrame rst(
13630 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13631 MockWrite writes1[] = {
13632 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13633 CreateMockWrite(rst, 6),
13634 };
13635
13636 // The first one succeeds, the second gets error 421 Misdirected Request.
13637 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13638 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13639 SpdyHeaderBlock response_headers;
13640 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13641 SpdySerializedFrame resp2(
13642 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13643 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13644 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13645
13646 MockConnect connect1(ASYNC, OK, peer_addr);
13647 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13648 arraysize(writes1));
13649 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13650
13651 AddSSLSocketData();
13652
13653 // Retry the second request on a second connection.
13654 SpdyTestUtil spdy_util2;
13655 SpdySerializedFrame req3(
13656 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13657 MockWrite writes2[] = {
13658 CreateMockWrite(req3, 0),
13659 };
13660
13661 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13662 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13663 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13664 MockRead(ASYNC, 0, 3)};
13665
13666 MockConnect connect2(ASYNC, OK, peer_addr);
13667 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13668 arraysize(writes2));
13669 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13670
13671 AddSSLSocketData();
13672
13673 // Preload mail.example.org into HostCache.
13674 HostPortPair host_port("mail.example.org", 443);
13675 HostResolver::RequestInfo resolve_info(host_port);
13676 AddressList ignored;
13677 std::unique_ptr<HostResolver::Request> request;
13678 TestCompletionCallback callback;
13679 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13680 &ignored, callback.callback(),
13681 &request, NetLogWithSource());
13682 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13683 rv = callback.WaitForResult();
13684 EXPECT_THAT(rv, IsOk());
13685
13686 HttpRequestInfo request1;
13687 request1.method = "GET";
13688 request1.url = GURL("https://www.example.org/");
13689 request1.load_flags = 0;
13690 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13691
13692 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13694 rv = callback.WaitForResult();
13695 EXPECT_THAT(rv, IsOk());
13696
13697 const HttpResponseInfo* response = trans1.GetResponseInfo();
13698 ASSERT_TRUE(response);
13699 ASSERT_TRUE(response->headers);
13700 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13701 EXPECT_TRUE(response->was_fetched_via_spdy);
13702 EXPECT_TRUE(response->was_alpn_negotiated);
13703 std::string response_data;
13704 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13705 EXPECT_EQ("hello!", response_data);
13706
13707 HttpRequestInfo request2;
13708 request2.method = "GET";
13709 request2.url = GURL("https://mail.example.org/");
13710 request2.load_flags = 0;
13711 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13712
13713 BoundTestNetLog log;
13714 rv = trans2.Start(&request2, callback.callback(), log.bound());
13715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13716 rv = callback.WaitForResult();
13717 EXPECT_THAT(rv, IsOk());
13718
13719 response = trans2.GetResponseInfo();
13720 ASSERT_TRUE(response);
13721 ASSERT_TRUE(response->headers);
13722 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13723 EXPECT_TRUE(response->was_fetched_via_spdy);
13724 EXPECT_TRUE(response->was_alpn_negotiated);
13725 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13726 EXPECT_EQ("hello!", response_data);
13727
13728 TestNetLogEntry::List entries;
13729 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5913730 ExpectLogContainsSomewhere(
13731 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2913732 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5913733}
13734
13735// Test that HTTP 421 responses are properly returned to the caller if received
13736// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
13737// portions of the response.
13738TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
13739 // Two hosts resolve to the same IP address.
13740 const std::string ip_addr = "1.2.3.4";
13741 IPAddress ip;
13742 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13743 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13744
bnc87dcefc2017-05-25 12:47:5813745 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5913746 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13747 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13748
13749 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13750
13751 // Two requests on the first connection.
13752 SpdySerializedFrame req1(
13753 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13754 spdy_util_.UpdateWithStreamDestruction(1);
13755 SpdySerializedFrame req2(
13756 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13757 SpdySerializedFrame rst(
13758 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13759 MockWrite writes1[] = {
13760 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13761 CreateMockWrite(rst, 6),
13762 };
13763
13764 // The first one succeeds, the second gets error 421 Misdirected Request.
13765 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13766 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13767 SpdyHeaderBlock response_headers;
13768 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13769 SpdySerializedFrame resp2(
13770 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
13771 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13772 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13773
13774 MockConnect connect1(ASYNC, OK, peer_addr);
13775 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13776 arraysize(writes1));
13777 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13778
13779 AddSSLSocketData();
13780
13781 // Retry the second request on a second connection. It returns 421 Misdirected
13782 // Retry again.
13783 SpdyTestUtil spdy_util2;
13784 SpdySerializedFrame req3(
13785 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13786 MockWrite writes2[] = {
13787 CreateMockWrite(req3, 0),
13788 };
13789
13790 SpdySerializedFrame resp3(
13791 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
13792 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13793 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13794 MockRead(ASYNC, 0, 3)};
13795
13796 MockConnect connect2(ASYNC, OK, peer_addr);
13797 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13798 arraysize(writes2));
13799 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13800
13801 AddSSLSocketData();
13802
13803 // Preload mail.example.org into HostCache.
13804 HostPortPair host_port("mail.example.org", 443);
13805 HostResolver::RequestInfo resolve_info(host_port);
13806 AddressList ignored;
13807 std::unique_ptr<HostResolver::Request> request;
13808 TestCompletionCallback callback;
13809 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13810 &ignored, callback.callback(),
13811 &request, NetLogWithSource());
13812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13813 rv = callback.WaitForResult();
13814 EXPECT_THAT(rv, IsOk());
13815
13816 HttpRequestInfo request1;
13817 request1.method = "GET";
13818 request1.url = GURL("https://www.example.org/");
13819 request1.load_flags = 0;
13820 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13821
13822 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13824 rv = callback.WaitForResult();
13825 EXPECT_THAT(rv, IsOk());
13826
13827 const HttpResponseInfo* response = trans1.GetResponseInfo();
13828 ASSERT_TRUE(response);
13829 ASSERT_TRUE(response->headers);
13830 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13831 EXPECT_TRUE(response->was_fetched_via_spdy);
13832 EXPECT_TRUE(response->was_alpn_negotiated);
13833 std::string response_data;
13834 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13835 EXPECT_EQ("hello!", response_data);
13836
13837 HttpRequestInfo request2;
13838 request2.method = "GET";
13839 request2.url = GURL("https://mail.example.org/");
13840 request2.load_flags = 0;
13841 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13842
13843 BoundTestNetLog log;
13844 rv = trans2.Start(&request2, callback.callback(), log.bound());
13845 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13846 rv = callback.WaitForResult();
13847 EXPECT_THAT(rv, IsOk());
13848
13849 // After a retry, the 421 Misdirected Request is reported back up to the
13850 // caller.
13851 response = trans2.GetResponseInfo();
13852 ASSERT_TRUE(response);
13853 ASSERT_TRUE(response->headers);
13854 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
13855 EXPECT_TRUE(response->was_fetched_via_spdy);
13856 EXPECT_TRUE(response->was_alpn_negotiated);
13857 EXPECT_TRUE(response->ssl_info.cert);
13858 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13859 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2913860}
13861
bnc6dcd8192017-05-25 20:11:5013862class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4613863 public:
13864 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5013865 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013866 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613867
dchengb03027d2014-10-21 12:00:2013868 int ResolveFromCache(const RequestInfo& info,
13869 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013870 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5013871 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4013872 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5013873 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613874 return rv;
13875 }
13876
[email protected]e3ceb682011-06-28 23:55:4613877 private:
[email protected]e3ceb682011-06-28 23:55:4613878 const HostPortPair host_port_;
13879};
13880
bncd16676a2016-07-20 16:23:0113881TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313882 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613883 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnc6dcd8192017-05-25 20:11:5013884 session_deps_.host_resolver = base::MakeUnique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3713885 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0913886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613887
bnc032658ba2016-09-26 18:17:1513888 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613889
bncdf80d44fd2016-07-15 20:27:4113890 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913891 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813892 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113893 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713894 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613895 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113896 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613897 };
bnc42331402016-07-25 13:36:1513898 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113899 SpdySerializedFrame host1_resp_body(
13900 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513901 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113902 SpdySerializedFrame host2_resp_body(
13903 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613904 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113905 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13906 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313907 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613908 };
13909
eroman36d84e54432016-03-17 03:23:0213910 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213911 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313912 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13913 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713914 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613915
[email protected]aa22b242011-11-16 18:58:2913916 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613917 HttpRequestInfo request1;
13918 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313919 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613920 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013921 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613922
tfarina42834112016-09-22 13:38:2013923 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113924 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13925 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613926
13927 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213928 ASSERT_TRUE(response);
13929 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213930 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613931
13932 std::string response_data;
robpercival214763f2016-07-01 23:27:0113933 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613934 EXPECT_EQ("hello!", response_data);
13935
13936 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713937 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613938 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013939 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5013940 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13941 &ignored, callback.callback(),
13942 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713944 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113945 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613946
13947 HttpRequestInfo request2;
13948 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713949 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613950 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013951 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613952
tfarina42834112016-09-22 13:38:2013953 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13955 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613956
13957 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213958 ASSERT_TRUE(response);
13959 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213960 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613961 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213962 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113963 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613964 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613965}
13966
bncd16676a2016-07-20 16:23:0113967TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313968 const std::string https_url = "https://www.example.org:8080/";
13969 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413970
13971 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113972 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913973 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413974
13975 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113976 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413977 };
13978
bnc42331402016-07-25 13:36:1513979 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113980 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13981 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913982 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413983
rch8e6c6c42015-05-01 14:05:1313984 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13985 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413986 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713987 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413988
13989 // HTTP GET for the HTTP URL
13990 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313991 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413992 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313993 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413994 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413995 };
13996
13997 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313998 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13999 MockRead(ASYNC, 2, "hello"),
14000 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414001 };
14002
rch8e6c6c42015-05-01 14:05:1314003 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14004 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414005
[email protected]8450d722012-07-02 19:14:0414006 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614007 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714008 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14009 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14010 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414011
danakj1fd259a02016-04-16 03:17:0914012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414013
14014 // Start the first transaction to set up the SpdySession
14015 HttpRequestInfo request1;
14016 request1.method = "GET";
14017 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414018 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014019 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414020 TestCompletionCallback callback1;
14021 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014022 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514023 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414024
robpercival214763f2016-07-01 23:27:0114025 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414026 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14027
14028 // Now, start the HTTP request
14029 HttpRequestInfo request2;
14030 request2.method = "GET";
14031 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414032 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014033 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414034 TestCompletionCallback callback2;
14035 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014036 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514037 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414038
robpercival214763f2016-07-01 23:27:0114039 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414040 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14041}
14042
bnc5452e2a2015-05-08 16:27:4214043// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14044// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114045TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514046 url::SchemeHostPort server("https", "www.example.org", 443);
14047 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214048
bnc8bef8da22016-05-30 01:28:2514049 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214050 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614051 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14053
14054 // No data should be read from the alternative, because HTTP/1.1 is
14055 // negotiated.
14056 StaticSocketDataProvider data;
14057 session_deps_.socket_factory->AddSocketDataProvider(&data);
14058
14059 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614060 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214061 // mocked. This way the request relies on the alternate Job.
14062 StaticSocketDataProvider data_refused;
14063 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14064 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14065
zhongyi3d4a55e72016-04-22 20:36:4614066 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014068 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214069 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114070 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214071 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114072 http_server_properties->SetHttp2AlternativeService(
14073 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214074
bnc5452e2a2015-05-08 16:27:4214075 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614076 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214077 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514078 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214079 TestCompletionCallback callback;
14080
14081 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214082 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014083 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214084 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214085}
14086
bnc40448a532015-05-11 19:13:1414087// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614088// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414089// succeeds, the request should succeed, even if the latter fails because
14090// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114091TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514092 url::SchemeHostPort server("https", "www.example.org", 443);
14093 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414094
14095 // Negotiate HTTP/1.1 with alternative.
14096 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614097 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414098 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14099
14100 // No data should be read from the alternative, because HTTP/1.1 is
14101 // negotiated.
14102 StaticSocketDataProvider data;
14103 session_deps_.socket_factory->AddSocketDataProvider(&data);
14104
zhongyi3d4a55e72016-04-22 20:36:4614105 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414106 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614107 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414108 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14109
14110 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514111 MockWrite("GET / HTTP/1.1\r\n"
14112 "Host: www.example.org\r\n"
14113 "Connection: keep-alive\r\n\r\n"),
14114 MockWrite("GET /second HTTP/1.1\r\n"
14115 "Host: www.example.org\r\n"
14116 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414117 };
14118
14119 MockRead http_reads[] = {
14120 MockRead("HTTP/1.1 200 OK\r\n"),
14121 MockRead("Content-Type: text/html\r\n"),
14122 MockRead("Content-Length: 6\r\n\r\n"),
14123 MockRead("foobar"),
14124 MockRead("HTTP/1.1 200 OK\r\n"),
14125 MockRead("Content-Type: text/html\r\n"),
14126 MockRead("Content-Length: 7\r\n\r\n"),
14127 MockRead("another"),
14128 };
14129 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14130 http_writes, arraysize(http_writes));
14131 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14132
zhongyi3d4a55e72016-04-22 20:36:4614133 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014135 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414136 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114137 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214138 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114139 http_server_properties->SetHttp2AlternativeService(
14140 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414141
14142 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14143 HttpRequestInfo request1;
14144 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514145 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414146 request1.load_flags = 0;
14147 TestCompletionCallback callback1;
14148
tfarina42834112016-09-22 13:38:2014149 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414150 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114151 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414152
14153 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214154 ASSERT_TRUE(response1);
14155 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414156 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14157
14158 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114159 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414160 EXPECT_EQ("foobar", response_data1);
14161
14162 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14163 // for alternative service.
14164 EXPECT_TRUE(
14165 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14166
zhongyi3d4a55e72016-04-22 20:36:4614167 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414168 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614169 // to server.
bnc40448a532015-05-11 19:13:1414170 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14171 HttpRequestInfo request2;
14172 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514173 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414174 request2.load_flags = 0;
14175 TestCompletionCallback callback2;
14176
tfarina42834112016-09-22 13:38:2014177 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414178 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114179 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414180
14181 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214182 ASSERT_TRUE(response2);
14183 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414184 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14185
14186 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114187 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414188 EXPECT_EQ("another", response_data2);
14189}
14190
bnc5452e2a2015-05-08 16:27:4214191// Alternative service requires HTTP/2 (or SPDY), but there is already a
14192// HTTP/1.1 socket open to the alternative server. That socket should not be
14193// used.
bncd16676a2016-07-20 16:23:0114194TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614195 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214196 HostPortPair alternative("alternative.example.org", 443);
14197 std::string origin_url = "https://origin.example.org:443";
14198 std::string alternative_url = "https://alternative.example.org:443";
14199
14200 // Negotiate HTTP/1.1 with alternative.example.org.
14201 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614202 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214203 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14204
14205 // HTTP/1.1 data for |request1| and |request2|.
14206 MockWrite http_writes[] = {
14207 MockWrite(
14208 "GET / HTTP/1.1\r\n"
14209 "Host: alternative.example.org\r\n"
14210 "Connection: keep-alive\r\n\r\n"),
14211 MockWrite(
14212 "GET / HTTP/1.1\r\n"
14213 "Host: alternative.example.org\r\n"
14214 "Connection: keep-alive\r\n\r\n"),
14215 };
14216
14217 MockRead http_reads[] = {
14218 MockRead(
14219 "HTTP/1.1 200 OK\r\n"
14220 "Content-Type: text/html; charset=iso-8859-1\r\n"
14221 "Content-Length: 40\r\n\r\n"
14222 "first HTTP/1.1 response from alternative"),
14223 MockRead(
14224 "HTTP/1.1 200 OK\r\n"
14225 "Content-Type: text/html; charset=iso-8859-1\r\n"
14226 "Content-Length: 41\r\n\r\n"
14227 "second HTTP/1.1 response from alternative"),
14228 };
14229 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14230 http_writes, arraysize(http_writes));
14231 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14232
14233 // This test documents that an alternate Job should not pool to an already
14234 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614235 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214236 StaticSocketDataProvider data_refused;
14237 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14238 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14239
zhongyi3d4a55e72016-04-22 20:36:4614240 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914241 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014242 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214243 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114244 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214245 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114246 http_server_properties->SetHttp2AlternativeService(
14247 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214248
14249 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214250 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614251 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214252 request1.method = "GET";
14253 request1.url = GURL(alternative_url);
14254 request1.load_flags = 0;
14255 TestCompletionCallback callback1;
14256
tfarina42834112016-09-22 13:38:2014257 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114258 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614259 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214260 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214261 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214262 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214263 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214264 EXPECT_FALSE(response1->was_fetched_via_spdy);
14265 std::string response_data1;
bnc691fda62016-08-12 00:43:1614266 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214267 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14268
14269 // Request for origin.example.org, which has an alternative service. This
14270 // will start two Jobs: the alternative looks for connections to pool to,
14271 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614272 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214273 // this request fails.
bnc5452e2a2015-05-08 16:27:4214274 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614275 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214276 request2.method = "GET";
14277 request2.url = GURL(origin_url);
14278 request2.load_flags = 0;
14279 TestCompletionCallback callback2;
14280
tfarina42834112016-09-22 13:38:2014281 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114282 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214283
14284 // Another transaction to alternative. This is to test that the HTTP/1.1
14285 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214286 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614287 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214288 request3.method = "GET";
14289 request3.url = GURL(alternative_url);
14290 request3.load_flags = 0;
14291 TestCompletionCallback callback3;
14292
tfarina42834112016-09-22 13:38:2014293 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114294 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614295 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214296 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214297 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214298 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214299 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214300 EXPECT_FALSE(response3->was_fetched_via_spdy);
14301 std::string response_data3;
bnc691fda62016-08-12 00:43:1614302 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214303 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14304}
14305
bncd16676a2016-07-20 16:23:0114306TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314307 const std::string https_url = "https://www.example.org:8080/";
14308 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414309
rdsmithebb50aa2015-11-12 03:44:3814310 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114311 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814312
[email protected]8450d722012-07-02 19:14:0414313 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314314 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114315 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414316 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114317 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914318 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114319 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214320 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914321
14322 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914323 SpdyHeaderBlock req2_block;
14324 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314325 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914326 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914327 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114328 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514329 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414330
14331 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114332 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14333 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414334 };
14335
bncdf80d44fd2016-07-15 20:27:4114336 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514337 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114338 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514339 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114340 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14341 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814342 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114343 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814344 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514345 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114346 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314347 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114348 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314349 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114350 CreateMockRead(wrapped_resp1, 4),
14351 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314352 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114353 CreateMockRead(resp2, 8),
14354 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314355 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14356 };
[email protected]8450d722012-07-02 19:14:0414357
mmenke666a6fea2015-12-19 04:16:3314358 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14359 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414360 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714361 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414362
rdsmith82957ad2015-09-16 19:42:0314363 session_deps_.proxy_service =
14364 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114365 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714366 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414367 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614368 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414370 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614371 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14373 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414374
danakj1fd259a02016-04-16 03:17:0914375 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414376
14377 // Start the first transaction to set up the SpdySession
14378 HttpRequestInfo request1;
14379 request1.method = "GET";
14380 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414381 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014382 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414383 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014384 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414385
mmenke666a6fea2015-12-19 04:16:3314386 // This pause is a hack to avoid running into https://crbug.com/497228.
14387 data1.RunUntilPaused();
14388 base::RunLoop().RunUntilIdle();
14389 data1.Resume();
robpercival214763f2016-07-01 23:27:0114390 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414391 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14392
[email protected]f6c63db52013-02-02 00:35:2214393 LoadTimingInfo load_timing_info1;
14394 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14395 TestLoadTimingNotReusedWithPac(load_timing_info1,
14396 CONNECT_TIMING_HAS_SSL_TIMES);
14397
mmenke666a6fea2015-12-19 04:16:3314398 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414399 HttpRequestInfo request2;
14400 request2.method = "GET";
14401 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414402 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014403 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414404 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014405 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414406
mmenke666a6fea2015-12-19 04:16:3314407 // This pause is a hack to avoid running into https://crbug.com/497228.
14408 data1.RunUntilPaused();
14409 base::RunLoop().RunUntilIdle();
14410 data1.Resume();
robpercival214763f2016-07-01 23:27:0114411 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314412
[email protected]8450d722012-07-02 19:14:0414413 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214414
14415 LoadTimingInfo load_timing_info2;
14416 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14417 // The established SPDY sessions is considered reused by the HTTP request.
14418 TestLoadTimingReusedWithPac(load_timing_info2);
14419 // HTTP requests over a SPDY session should have a different connection
14420 // socket_log_id than requests over a tunnel.
14421 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414422}
14423
[email protected]2d88e7d2012-07-19 17:55:1714424// Test that in the case where we have a SPDY session to a SPDY proxy
14425// that we do not pool other origins that resolve to the same IP when
14426// the certificate does not match the new origin.
14427// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114428TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314429 const std::string url1 = "http://www.example.org/";
14430 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714431 const std::string ip_addr = "1.2.3.4";
14432
rdsmithebb50aa2015-11-12 03:44:3814433 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114434 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814435
[email protected]2d88e7d2012-07-19 17:55:1714436 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614437 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314438 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114439 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514440 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714441
14442 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114443 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714444 };
14445
bnc42331402016-07-25 13:36:1514446 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114447 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714448 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114449 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14450 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714451 };
14452
mmenke666a6fea2015-12-19 04:16:3314453 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14454 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214455 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914456 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714457 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14458 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314459 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714460
14461 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114462 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914463 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714464
14465 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114466 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714467 };
14468
bnc42331402016-07-25 13:36:1514469 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114470 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14471 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314472 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714473
mmenke666a6fea2015-12-19 04:16:3314474 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14475 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714476 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314477 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714478
14479 // Set up a proxy config that sends HTTP requests to a proxy, and
14480 // all others direct.
14481 ProxyConfig proxy_config;
14482 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
bnc87dcefc2017-05-25 12:47:5814483 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
14484 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), nullptr,
14485 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714486
bncce36dca22015-04-21 22:11:2314487 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614488 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714489 // Load a valid cert. Note, that this does not need to
14490 // be valid for proxy because the MockSSLClientSocket does
14491 // not actually verify it. But SpdySession will use this
14492 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314493 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214494 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14496 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714497
14498 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614499 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14501 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714502
bnc87dcefc2017-05-25 12:47:5814503 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314504 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714505 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714506
danakj1fd259a02016-04-16 03:17:0914507 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714508
14509 // Start the first transaction to set up the SpdySession
14510 HttpRequestInfo request1;
14511 request1.method = "GET";
14512 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714513 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014514 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714515 TestCompletionCallback callback1;
14516 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014517 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314518 // This pause is a hack to avoid running into https://crbug.com/497228.
14519 data1.RunUntilPaused();
14520 base::RunLoop().RunUntilIdle();
14521 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714522
robpercival214763f2016-07-01 23:27:0114523 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714524 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14525
14526 // Now, start the HTTP request
14527 HttpRequestInfo request2;
14528 request2.method = "GET";
14529 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714530 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014531 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714532 TestCompletionCallback callback2;
14533 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014534 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514535 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714536
14537 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114538 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714539 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14540}
14541
[email protected]85f97342013-04-17 06:12:2414542// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14543// error) in SPDY session, removes the socket from pool and closes the SPDY
14544// session. Verify that new url's from the same HttpNetworkSession (and a new
14545// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114546TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314547 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414548
14549 MockRead reads1[] = {
14550 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14551 };
14552
mmenke11eb5152015-06-09 14:50:5014553 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414554
bncdf80d44fd2016-07-15 20:27:4114555 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914556 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414557 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114558 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414559 };
14560
bnc42331402016-07-25 13:36:1514561 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114562 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414563 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114564 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14565 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414566 };
14567
mmenke11eb5152015-06-09 14:50:5014568 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14569 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414570
[email protected]85f97342013-04-17 06:12:2414571 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614572 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014573 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14574 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414575
14576 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614577 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014578 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14579 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414580
danakj1fd259a02016-04-16 03:17:0914581 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014582 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414583
14584 // Start the first transaction to set up the SpdySession and verify that
14585 // connection was closed.
14586 HttpRequestInfo request1;
14587 request1.method = "GET";
14588 request1.url = GURL(https_url);
14589 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014590 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414591 TestCompletionCallback callback1;
14592 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014593 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114594 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414595
14596 // Now, start the second request and make sure it succeeds.
14597 HttpRequestInfo request2;
14598 request2.method = "GET";
14599 request2.url = GURL(https_url);
14600 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014601 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414602 TestCompletionCallback callback2;
14603 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014604 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414605
robpercival214763f2016-07-01 23:27:0114606 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414607 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14608}
14609
bncd16676a2016-07-20 16:23:0114610TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314611 ClientSocketPoolManager::set_max_sockets_per_group(
14612 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14613 ClientSocketPoolManager::set_max_sockets_per_pool(
14614 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14615
14616 // Use two different hosts with different IPs so they don't get pooled.
14617 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14618 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314620
14621 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614622 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314623 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614624 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14627
bncdf80d44fd2016-07-15 20:27:4114628 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914629 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314630 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114631 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314632 };
bnc42331402016-07-25 13:36:1514633 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114634 SpdySerializedFrame host1_resp_body(
14635 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314636 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114637 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914638 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314639 };
14640
rdsmithebb50aa2015-11-12 03:44:3814641 // Use a separate test instance for the separate SpdySession that will be
14642 // created.
bncd16676a2016-07-20 16:23:0114643 SpdyTestUtil spdy_util_2;
bnc87dcefc2017-05-25 12:47:5814644 auto spdy1_data = base::MakeUnique<SequencedSocketData>(
14645 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14646 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0314647 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14648
bncdf80d44fd2016-07-15 20:27:4114649 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914650 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314651 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114652 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314653 };
bnc42331402016-07-25 13:36:1514654 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114655 SpdySerializedFrame host2_resp_body(
14656 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314657 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114658 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914659 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314660 };
14661
bnc87dcefc2017-05-25 12:47:5814662 auto spdy2_data = base::MakeUnique<SequencedSocketData>(
14663 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14664 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0314665 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14666
14667 MockWrite http_write[] = {
14668 MockWrite("GET / HTTP/1.1\r\n"
14669 "Host: www.a.com\r\n"
14670 "Connection: keep-alive\r\n\r\n"),
14671 };
14672
14673 MockRead http_read[] = {
14674 MockRead("HTTP/1.1 200 OK\r\n"),
14675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14676 MockRead("Content-Length: 6\r\n\r\n"),
14677 MockRead("hello!"),
14678 };
14679 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14680 http_write, arraysize(http_write));
14681 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14682
14683 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014684 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314685 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314686 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614687 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314688
14689 TestCompletionCallback callback;
14690 HttpRequestInfo request1;
14691 request1.method = "GET";
14692 request1.url = GURL("https://www.a.com/");
14693 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814694 auto trans =
14695 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314696
tfarina42834112016-09-22 13:38:2014697 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14699 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314700
14701 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214702 ASSERT_TRUE(response);
14703 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214704 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314705 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214706 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314707
14708 std::string response_data;
robpercival214763f2016-07-01 23:27:0114709 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314710 EXPECT_EQ("hello!", response_data);
14711 trans.reset();
14712 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614713 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314714
14715 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014716 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314717 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314718 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614719 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314720 HttpRequestInfo request2;
14721 request2.method = "GET";
14722 request2.url = GURL("https://www.b.com/");
14723 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814724 trans =
14725 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314726
tfarina42834112016-09-22 13:38:2014727 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14729 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314730
14731 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214732 ASSERT_TRUE(response);
14733 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214734 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314735 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214736 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114737 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314738 EXPECT_EQ("hello!", response_data);
14739 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614740 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314741 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614742 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314743
14744 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014745 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314746 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314747 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614748 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314749 HttpRequestInfo request3;
14750 request3.method = "GET";
14751 request3.url = GURL("http://www.a.com/");
14752 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814753 trans =
14754 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314755
tfarina42834112016-09-22 13:38:2014756 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14758 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314759
14760 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214761 ASSERT_TRUE(response);
14762 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314763 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14764 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214765 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114766 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314767 EXPECT_EQ("hello!", response_data);
14768 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614769 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314770 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614771 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314772}
14773
bncd16676a2016-07-20 16:23:0114774TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414775 HttpRequestInfo request;
14776 request.method = "GET";
bncce36dca22015-04-21 22:11:2314777 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414778
danakj1fd259a02016-04-16 03:17:0914779 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614780 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414781
ttuttled9dbc652015-09-29 20:00:5914782 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414783 StaticSocketDataProvider data;
14784 data.set_connect_data(mock_connect);
14785 session_deps_.socket_factory->AddSocketDataProvider(&data);
14786
14787 TestCompletionCallback callback;
14788
tfarina42834112016-09-22 13:38:2014789 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414791
14792 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114793 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414794
[email protected]79e1fd62013-06-20 06:50:0414795 // We don't care whether this succeeds or fails, but it shouldn't crash.
14796 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614797 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714798
14799 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614800 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714801 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114802 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914803
14804 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614805 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914806 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414807}
14808
bncd16676a2016-07-20 16:23:0114809TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414810 HttpRequestInfo request;
14811 request.method = "GET";
bncce36dca22015-04-21 22:11:2314812 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414813
danakj1fd259a02016-04-16 03:17:0914814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414816
ttuttled9dbc652015-09-29 20:00:5914817 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414818 StaticSocketDataProvider data;
14819 data.set_connect_data(mock_connect);
14820 session_deps_.socket_factory->AddSocketDataProvider(&data);
14821
14822 TestCompletionCallback callback;
14823
tfarina42834112016-09-22 13:38:2014824 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414826
14827 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114828 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414829
[email protected]79e1fd62013-06-20 06:50:0414830 // We don't care whether this succeeds or fails, but it shouldn't crash.
14831 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614832 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714833
14834 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614835 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714836 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114837 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914838
14839 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614840 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914841 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414842}
14843
bncd16676a2016-07-20 16:23:0114844TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414845 HttpRequestInfo request;
14846 request.method = "GET";
bncce36dca22015-04-21 22:11:2314847 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414848
danakj1fd259a02016-04-16 03:17:0914849 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414851
14852 MockWrite data_writes[] = {
14853 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14854 };
14855 MockRead data_reads[] = {
14856 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14857 };
14858
14859 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14860 data_writes, arraysize(data_writes));
14861 session_deps_.socket_factory->AddSocketDataProvider(&data);
14862
14863 TestCompletionCallback callback;
14864
tfarina42834112016-09-22 13:38:2014865 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414867
14868 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114869 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414870
[email protected]79e1fd62013-06-20 06:50:0414871 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614872 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414873 EXPECT_TRUE(request_headers.HasHeader("Host"));
14874}
14875
bncd16676a2016-07-20 16:23:0114876TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414877 HttpRequestInfo request;
14878 request.method = "GET";
bncce36dca22015-04-21 22:11:2314879 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414880
danakj1fd259a02016-04-16 03:17:0914881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614882 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414883
14884 MockWrite data_writes[] = {
14885 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14886 };
14887 MockRead data_reads[] = {
14888 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14889 };
14890
14891 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14892 data_writes, arraysize(data_writes));
14893 session_deps_.socket_factory->AddSocketDataProvider(&data);
14894
14895 TestCompletionCallback callback;
14896
tfarina42834112016-09-22 13:38:2014897 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414899
14900 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114901 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414902
[email protected]79e1fd62013-06-20 06:50:0414903 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614904 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414905 EXPECT_TRUE(request_headers.HasHeader("Host"));
14906}
14907
bncd16676a2016-07-20 16:23:0114908TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414909 HttpRequestInfo request;
14910 request.method = "GET";
bncce36dca22015-04-21 22:11:2314911 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414912
danakj1fd259a02016-04-16 03:17:0914913 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614914 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414915
14916 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314917 MockWrite(
14918 "GET / HTTP/1.1\r\n"
14919 "Host: www.example.org\r\n"
14920 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414921 };
14922 MockRead data_reads[] = {
14923 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14924 };
14925
14926 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14927 data_writes, arraysize(data_writes));
14928 session_deps_.socket_factory->AddSocketDataProvider(&data);
14929
14930 TestCompletionCallback callback;
14931
tfarina42834112016-09-22 13:38:2014932 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414934
14935 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114936 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414937
[email protected]79e1fd62013-06-20 06:50:0414938 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614939 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414940 EXPECT_TRUE(request_headers.HasHeader("Host"));
14941}
14942
bncd16676a2016-07-20 16:23:0114943TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414944 HttpRequestInfo request;
14945 request.method = "GET";
bncce36dca22015-04-21 22:11:2314946 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414947
danakj1fd259a02016-04-16 03:17:0914948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414950
14951 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314952 MockWrite(
14953 "GET / HTTP/1.1\r\n"
14954 "Host: www.example.org\r\n"
14955 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414956 };
14957 MockRead data_reads[] = {
14958 MockRead(ASYNC, ERR_CONNECTION_RESET),
14959 };
14960
14961 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14962 data_writes, arraysize(data_writes));
14963 session_deps_.socket_factory->AddSocketDataProvider(&data);
14964
14965 TestCompletionCallback callback;
14966
tfarina42834112016-09-22 13:38:2014967 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414969
14970 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114971 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414972
[email protected]79e1fd62013-06-20 06:50:0414973 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614974 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414975 EXPECT_TRUE(request_headers.HasHeader("Host"));
14976}
14977
bncd16676a2016-07-20 16:23:0114978TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414979 HttpRequestInfo request;
14980 request.method = "GET";
bncce36dca22015-04-21 22:11:2314981 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414982 request.extra_headers.SetHeader("X-Foo", "bar");
14983
danakj1fd259a02016-04-16 03:17:0914984 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414986
14987 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314988 MockWrite(
14989 "GET / HTTP/1.1\r\n"
14990 "Host: www.example.org\r\n"
14991 "Connection: keep-alive\r\n"
14992 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414993 };
14994 MockRead data_reads[] = {
14995 MockRead("HTTP/1.1 200 OK\r\n"
14996 "Content-Length: 5\r\n\r\n"
14997 "hello"),
14998 MockRead(ASYNC, ERR_UNEXPECTED),
14999 };
15000
15001 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15002 data_writes, arraysize(data_writes));
15003 session_deps_.socket_factory->AddSocketDataProvider(&data);
15004
15005 TestCompletionCallback callback;
15006
tfarina42834112016-09-22 13:38:2015007 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415009
15010 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115011 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415012
15013 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615014 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415015 std::string foo;
15016 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15017 EXPECT_EQ("bar", foo);
15018}
15019
[email protected]bf828982013-08-14 18:01:4715020namespace {
15021
yhiranoa7e05bb2014-11-06 05:40:3915022// Fake HttpStream that simply records calls to SetPriority().
15023class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315024 public base::SupportsWeakPtr<FakeStream> {
15025 public:
15026 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015027 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315028
15029 RequestPriority priority() const { return priority_; }
15030
dchengb03027d2014-10-21 12:00:2015031 int InitializeStream(const HttpRequestInfo* request_info,
15032 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015033 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015034 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315035 return ERR_IO_PENDING;
15036 }
15037
dchengb03027d2014-10-21 12:00:2015038 int SendRequest(const HttpRequestHeaders& request_headers,
15039 HttpResponseInfo* response,
15040 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315041 ADD_FAILURE();
15042 return ERR_UNEXPECTED;
15043 }
15044
dchengb03027d2014-10-21 12:00:2015045 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315046 ADD_FAILURE();
15047 return ERR_UNEXPECTED;
15048 }
15049
dchengb03027d2014-10-21 12:00:2015050 int ReadResponseBody(IOBuffer* buf,
15051 int buf_len,
15052 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315053 ADD_FAILURE();
15054 return ERR_UNEXPECTED;
15055 }
15056
dchengb03027d2014-10-21 12:00:2015057 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315058
dchengb03027d2014-10-21 12:00:2015059 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315060 ADD_FAILURE();
15061 return false;
15062 }
15063
dchengb03027d2014-10-21 12:00:2015064 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315065 ADD_FAILURE();
15066 return false;
15067 }
15068
dchengb03027d2014-10-21 12:00:2015069 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315070
mmenkebd84c392015-09-02 14:12:3415071 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315072
sclittle4de1bab92015-09-22 21:28:2415073 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915074 ADD_FAILURE();
15075 return 0;
15076 }
15077
sclittlebe1ccf62015-09-02 19:40:3615078 int64_t GetTotalSentBytes() const override {
15079 ADD_FAILURE();
15080 return 0;
15081 }
15082
dchengb03027d2014-10-21 12:00:2015083 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315084 ADD_FAILURE();
15085 return false;
15086 }
15087
rchcd379012017-04-12 21:53:3215088 bool GetAlternativeService(
15089 AlternativeService* alternative_service) const override {
15090 ADD_FAILURE();
15091 return false;
15092 }
15093
dchengb03027d2014-10-21 12:00:2015094 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15095
15096 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315097 ADD_FAILURE();
15098 }
15099
ttuttled9dbc652015-09-29 20:00:5915100 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15101
nharper78e6d2b2016-09-21 05:42:3515102 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15103 TokenBindingType tb_type,
15104 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415105 ADD_FAILURE();
15106 return ERR_NOT_IMPLEMENTED;
15107 }
15108
dchengb03027d2014-10-21 12:00:2015109 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315110
zhongyica364fbb2015-12-12 03:39:1215111 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15112
dchengb03027d2014-10-21 12:00:2015113 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315114
yhiranoa7e05bb2014-11-06 05:40:3915115 HttpStream* RenewStreamForAuth() override { return NULL; }
15116
[email protected]e86839fd2013-08-14 18:29:0315117 private:
15118 RequestPriority priority_;
15119
15120 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15121};
15122
15123// Fake HttpStreamRequest that simply records calls to SetPriority()
15124// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715125class FakeStreamRequest : public HttpStreamRequest,
15126 public base::SupportsWeakPtr<FakeStreamRequest> {
15127 public:
[email protected]e86839fd2013-08-14 18:29:0315128 FakeStreamRequest(RequestPriority priority,
15129 HttpStreamRequest::Delegate* delegate)
15130 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415131 delegate_(delegate),
15132 websocket_stream_create_helper_(NULL) {}
15133
15134 FakeStreamRequest(RequestPriority priority,
15135 HttpStreamRequest::Delegate* delegate,
15136 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15137 : priority_(priority),
15138 delegate_(delegate),
15139 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315140
dchengb03027d2014-10-21 12:00:2015141 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715142
15143 RequestPriority priority() const { return priority_; }
15144
[email protected]831e4a32013-11-14 02:14:4415145 const WebSocketHandshakeStreamBase::CreateHelper*
15146 websocket_stream_create_helper() const {
15147 return websocket_stream_create_helper_;
15148 }
15149
[email protected]e86839fd2013-08-14 18:29:0315150 // Create a new FakeStream and pass it to the request's
15151 // delegate. Returns a weak pointer to the FakeStream.
15152 base::WeakPtr<FakeStream> FinishStreamRequest() {
bnc5029f4632017-06-08 16:19:0015153 auto fake_stream = base::MakeUnique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315154 // Do this before calling OnStreamReady() as OnStreamReady() may
15155 // immediately delete |fake_stream|.
15156 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015157 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315158 return weak_stream;
15159 }
15160
asanka681f02d2017-02-22 17:06:3915161 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715162 ADD_FAILURE();
15163 return ERR_UNEXPECTED;
15164 }
15165
dchengb03027d2014-10-21 12:00:2015166 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715167 ADD_FAILURE();
15168 return LoadState();
15169 }
15170
dchengb03027d2014-10-21 12:00:2015171 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715172
bnc94c92842016-09-21 15:22:5215173 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715174
bnc6227b26e2016-08-12 02:00:4315175 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715176
dchengb03027d2014-10-21 12:00:2015177 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715178
ttuttle1f2d7e92015-04-28 16:17:4715179 const ConnectionAttempts& connection_attempts() const override {
15180 static ConnectionAttempts no_attempts;
15181 return no_attempts;
15182 }
15183
[email protected]bf828982013-08-14 18:01:4715184 private:
15185 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315186 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415187 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715188
15189 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15190};
15191
15192// Fake HttpStreamFactory that vends FakeStreamRequests.
15193class FakeStreamFactory : public HttpStreamFactory {
15194 public:
15195 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015196 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715197
15198 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15199 // RequestStream() (which may be NULL if it was destroyed already).
15200 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15201 return last_stream_request_;
15202 }
15203
xunjieli96f2a402017-06-05 17:24:2715204 std::unique_ptr<HttpStreamRequest> RequestStream(
15205 const HttpRequestInfo& info,
15206 RequestPriority priority,
15207 const SSLConfig& server_ssl_config,
15208 const SSLConfig& proxy_ssl_config,
15209 HttpStreamRequest::Delegate* delegate,
15210 bool enable_ip_based_pooling,
15211 bool enable_alternative_services,
15212 const NetLogWithSource& net_log) override {
15213 auto fake_request = base::MakeUnique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715214 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715215 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715216 }
15217
xunjieli96f2a402017-06-05 17:24:2715218 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815219 const HttpRequestInfo& info,
15220 RequestPriority priority,
15221 const SSLConfig& server_ssl_config,
15222 const SSLConfig& proxy_ssl_config,
15223 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915224 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615225 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015226 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815227 NOTREACHED();
15228 return nullptr;
15229 }
15230
xunjieli96f2a402017-06-05 17:24:2715231 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715232 const HttpRequestInfo& info,
15233 RequestPriority priority,
15234 const SSLConfig& server_ssl_config,
15235 const SSLConfig& proxy_ssl_config,
15236 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615237 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915238 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615239 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015240 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715241 auto fake_request =
15242 base::MakeUnique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415243 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715244 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715245 }
15246
dchengb03027d2014-10-21 12:00:2015247 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915248 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715249 ADD_FAILURE();
15250 }
15251
dchengb03027d2014-10-21 12:00:2015252 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715253 ADD_FAILURE();
15254 return NULL;
15255 }
15256
xunjielif5267de2017-01-20 21:18:5715257 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15258 const std::string& parent_absolute_name) const override {
15259 ADD_FAILURE();
15260 }
15261
[email protected]bf828982013-08-14 18:01:4715262 private:
15263 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15264
15265 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15266};
15267
Adam Rice425cf122015-01-19 06:18:2415268// TODO(ricea): Maybe unify this with the one in
15269// url_request_http_job_unittest.cc ?
15270class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15271 public:
danakj1fd259a02016-04-16 03:17:0915272 FakeWebSocketBasicHandshakeStream(
15273 std::unique_ptr<ClientSocketHandle> connection,
15274 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215275 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415276
15277 // Fake implementation of HttpStreamBase methods.
15278 // This ends up being quite "real" because this object has to really send data
15279 // on the mock socket. It might be easier to use the real implementation, but
15280 // the fact that the WebSocket code is not compiled on iOS makes that
15281 // difficult.
15282 int InitializeStream(const HttpRequestInfo* request_info,
15283 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015284 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415285 const CompletionCallback& callback) override {
15286 state_.Initialize(request_info, priority, net_log, callback);
15287 return OK;
15288 }
15289
15290 int SendRequest(const HttpRequestHeaders& request_headers,
15291 HttpResponseInfo* response,
15292 const CompletionCallback& callback) override {
15293 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15294 response, callback);
15295 }
15296
15297 int ReadResponseHeaders(const CompletionCallback& callback) override {
15298 return parser()->ReadResponseHeaders(callback);
15299 }
15300
15301 int ReadResponseBody(IOBuffer* buf,
15302 int buf_len,
15303 const CompletionCallback& callback) override {
15304 NOTREACHED();
15305 return ERR_IO_PENDING;
15306 }
15307
15308 void Close(bool not_reusable) override {
15309 if (parser())
15310 parser()->Close(true);
15311 }
15312
15313 bool IsResponseBodyComplete() const override {
15314 NOTREACHED();
15315 return false;
15316 }
15317
Adam Rice425cf122015-01-19 06:18:2415318 bool IsConnectionReused() const override {
15319 NOTREACHED();
15320 return false;
15321 }
15322 void SetConnectionReused() override { NOTREACHED(); }
15323
mmenkebd84c392015-09-02 14:12:3415324 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415325
sclittle4de1bab92015-09-22 21:28:2415326 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415327 NOTREACHED();
15328 return 0;
15329 }
15330
sclittlebe1ccf62015-09-02 19:40:3615331 int64_t GetTotalSentBytes() const override {
15332 NOTREACHED();
15333 return 0;
15334 }
15335
Adam Rice425cf122015-01-19 06:18:2415336 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15337 NOTREACHED();
15338 return false;
15339 }
15340
rchcd379012017-04-12 21:53:3215341 bool GetAlternativeService(
15342 AlternativeService* alternative_service) const override {
15343 ADD_FAILURE();
15344 return false;
15345 }
15346
Adam Ricecb76ac62015-02-20 05:33:2515347 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415348
15349 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15350 NOTREACHED();
15351 }
15352
ttuttled9dbc652015-09-29 20:00:5915353 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15354
nharper78e6d2b2016-09-21 05:42:3515355 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15356 TokenBindingType tb_type,
15357 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415358 ADD_FAILURE();
15359 return ERR_NOT_IMPLEMENTED;
15360 }
15361
Adam Rice425cf122015-01-19 06:18:2415362 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15363
zhongyica364fbb2015-12-12 03:39:1215364 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15365
Adam Rice425cf122015-01-19 06:18:2415366 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15367
Adam Rice425cf122015-01-19 06:18:2415368 HttpStream* RenewStreamForAuth() override {
15369 NOTREACHED();
15370 return nullptr;
15371 }
15372
15373 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915374 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415375 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915376 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415377 }
15378
15379 private:
15380 HttpStreamParser* parser() const { return state_.parser(); }
15381 HttpBasicState state_;
15382
15383 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15384};
15385
[email protected]831e4a32013-11-14 02:14:4415386// TODO(yhirano): Split this class out into a net/websockets file, if it is
15387// worth doing.
15388class FakeWebSocketStreamCreateHelper :
15389 public WebSocketHandshakeStreamBase::CreateHelper {
15390 public:
bnc615cf2f2017-05-19 18:53:2615391 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915392 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315393 bool using_proxy) override {
bnc615cf2f2017-05-19 18:53:2615394 return base::MakeUnique<FakeWebSocketBasicHandshakeStream>(
15395 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415396 }
15397
dchengb03027d2014-10-21 12:00:2015398 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415399
danakj1fd259a02016-04-16 03:17:0915400 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415401 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915402 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415403 }
15404};
15405
[email protected]bf828982013-08-14 18:01:4715406} // namespace
15407
15408// Make sure that HttpNetworkTransaction passes on its priority to its
15409// stream request on start.
bncd16676a2016-07-20 16:23:0115410TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915411 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215412 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715413 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915414 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715415
krasinc06a72a2016-12-21 03:42:4615416 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115417 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715418
wezca1070932016-05-26 20:30:5215419 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715420
[email protected]bf828982013-08-14 18:01:4715421 TestCompletionCallback callback;
15422 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015423 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715424
15425 base::WeakPtr<FakeStreamRequest> fake_request =
15426 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215427 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715428 EXPECT_EQ(LOW, fake_request->priority());
15429}
15430
15431// Make sure that HttpNetworkTransaction passes on its priority
15432// updates to its stream request.
bncd16676a2016-07-20 16:23:0115433TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915434 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215435 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715436 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915437 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715438
krasinc06a72a2016-12-21 03:42:4615439 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115440 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715441
[email protected]bf828982013-08-14 18:01:4715442 TestCompletionCallback callback;
15443 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015444 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715445
15446 base::WeakPtr<FakeStreamRequest> fake_request =
15447 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215448 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715449 EXPECT_EQ(LOW, fake_request->priority());
15450
15451 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215452 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715453 EXPECT_EQ(LOWEST, fake_request->priority());
15454}
15455
[email protected]e86839fd2013-08-14 18:29:0315456// Make sure that HttpNetworkTransaction passes on its priority
15457// updates to its stream.
bncd16676a2016-07-20 16:23:0115458TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215460 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315461 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915462 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315463
krasinc06a72a2016-12-21 03:42:4615464 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115465 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315466
[email protected]e86839fd2013-08-14 18:29:0315467 TestCompletionCallback callback;
15468 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015469 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315470
15471 base::WeakPtr<FakeStreamRequest> fake_request =
15472 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215473 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315474 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215475 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315476 EXPECT_EQ(LOW, fake_stream->priority());
15477
15478 trans.SetPriority(LOWEST);
15479 EXPECT_EQ(LOWEST, fake_stream->priority());
15480}
15481
bncd16676a2016-07-20 16:23:0115482TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415483 // The same logic needs to be tested for both ws: and wss: schemes, but this
15484 // test is already parameterised on NextProto, so it uses a loop to verify
15485 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315486 std::string test_cases[] = {"ws://www.example.org/",
15487 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415488 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915489 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215490 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415491 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15492 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315493 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915494 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415495
krasinc06a72a2016-12-21 03:42:4615496 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115497 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415498 trans.SetWebSocketHandshakeStreamCreateHelper(
15499 &websocket_stream_create_helper);
15500
[email protected]831e4a32013-11-14 02:14:4415501 TestCompletionCallback callback;
15502 request.method = "GET";
15503 request.url = GURL(test_cases[i]);
15504
15505 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015506 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415507
15508 base::WeakPtr<FakeStreamRequest> fake_request =
15509 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215510 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415511 EXPECT_EQ(&websocket_stream_create_helper,
15512 fake_request->websocket_stream_create_helper());
15513 }
15514}
15515
[email protected]043b68c82013-08-22 23:41:5215516// Tests that when a used socket is returned to the SSL socket pool, it's closed
15517// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115518TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215519 ClientSocketPoolManager::set_max_sockets_per_group(
15520 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15521 ClientSocketPoolManager::set_max_sockets_per_pool(
15522 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15523
15524 // Set up SSL request.
15525
15526 HttpRequestInfo ssl_request;
15527 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315528 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215529
15530 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315531 MockWrite(
15532 "GET / HTTP/1.1\r\n"
15533 "Host: www.example.org\r\n"
15534 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215535 };
15536 MockRead ssl_reads[] = {
15537 MockRead("HTTP/1.1 200 OK\r\n"),
15538 MockRead("Content-Length: 11\r\n\r\n"),
15539 MockRead("hello world"),
15540 MockRead(SYNCHRONOUS, OK),
15541 };
15542 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15543 ssl_writes, arraysize(ssl_writes));
15544 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15545
15546 SSLSocketDataProvider ssl(ASYNC, OK);
15547 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15548
15549 // Set up HTTP request.
15550
15551 HttpRequestInfo http_request;
15552 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315553 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215554
15555 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315556 MockWrite(
15557 "GET / HTTP/1.1\r\n"
15558 "Host: www.example.org\r\n"
15559 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215560 };
15561 MockRead http_reads[] = {
15562 MockRead("HTTP/1.1 200 OK\r\n"),
15563 MockRead("Content-Length: 7\r\n\r\n"),
15564 MockRead("falafel"),
15565 MockRead(SYNCHRONOUS, OK),
15566 };
15567 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15568 http_writes, arraysize(http_writes));
15569 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15570
danakj1fd259a02016-04-16 03:17:0915571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215572
15573 // Start the SSL request.
15574 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615575 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015576 ASSERT_EQ(ERR_IO_PENDING,
15577 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15578 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215579
15580 // Start the HTTP request. Pool should stall.
15581 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615582 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015583 ASSERT_EQ(ERR_IO_PENDING,
15584 http_trans.Start(&http_request, http_callback.callback(),
15585 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115586 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215587
15588 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115589 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215590 std::string response_data;
bnc691fda62016-08-12 00:43:1615591 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215592 EXPECT_EQ("hello world", response_data);
15593
15594 // The SSL socket should automatically be closed, so the HTTP request can
15595 // start.
dcheng48459ac22014-08-26 00:46:4115596 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15597 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215598
15599 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115600 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615601 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215602 EXPECT_EQ("falafel", response_data);
15603
dcheng48459ac22014-08-26 00:46:4115604 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215605}
15606
15607// Tests that when a SSL connection is established but there's no corresponding
15608// request that needs it, the new socket is closed if the transport socket pool
15609// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115610TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215611 ClientSocketPoolManager::set_max_sockets_per_group(
15612 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15613 ClientSocketPoolManager::set_max_sockets_per_pool(
15614 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15615
15616 // Set up an ssl request.
15617
15618 HttpRequestInfo ssl_request;
15619 ssl_request.method = "GET";
15620 ssl_request.url = GURL("https://www.foopy.com/");
15621
15622 // No data will be sent on the SSL socket.
15623 StaticSocketDataProvider ssl_data;
15624 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15625
15626 SSLSocketDataProvider ssl(ASYNC, OK);
15627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15628
15629 // Set up HTTP request.
15630
15631 HttpRequestInfo http_request;
15632 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315633 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215634
15635 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315636 MockWrite(
15637 "GET / HTTP/1.1\r\n"
15638 "Host: www.example.org\r\n"
15639 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215640 };
15641 MockRead http_reads[] = {
15642 MockRead("HTTP/1.1 200 OK\r\n"),
15643 MockRead("Content-Length: 7\r\n\r\n"),
15644 MockRead("falafel"),
15645 MockRead(SYNCHRONOUS, OK),
15646 };
15647 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15648 http_writes, arraysize(http_writes));
15649 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15650
danakj1fd259a02016-04-16 03:17:0915651 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215652
15653 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15654 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915655 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915656 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115657 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215658
15659 // Start the HTTP request. Pool should stall.
15660 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615661 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015662 ASSERT_EQ(ERR_IO_PENDING,
15663 http_trans.Start(&http_request, http_callback.callback(),
15664 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115665 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215666
15667 // The SSL connection will automatically be closed once the connection is
15668 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115669 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215670 std::string response_data;
bnc691fda62016-08-12 00:43:1615671 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215672 EXPECT_EQ("falafel", response_data);
15673
dcheng48459ac22014-08-26 00:46:4115674 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215675}
15676
bncd16676a2016-07-20 16:23:0115677TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915678 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215679 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715680 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215681 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415682
15683 HttpRequestInfo request;
15684 request.method = "POST";
15685 request.url = GURL("http://www.foo.com/");
15686 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415687
danakj1fd259a02016-04-16 03:17:0915688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415690 // Send headers successfully, but get an error while sending the body.
15691 MockWrite data_writes[] = {
15692 MockWrite("POST / HTTP/1.1\r\n"
15693 "Host: www.foo.com\r\n"
15694 "Connection: keep-alive\r\n"
15695 "Content-Length: 3\r\n\r\n"),
15696 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15697 };
15698
15699 MockRead data_reads[] = {
15700 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15701 MockRead("hello world"),
15702 MockRead(SYNCHRONOUS, OK),
15703 };
15704 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15705 arraysize(data_writes));
15706 session_deps_.socket_factory->AddSocketDataProvider(&data);
15707
15708 TestCompletionCallback callback;
15709
tfarina42834112016-09-22 13:38:2015710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415712
15713 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115714 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415715
bnc691fda62016-08-12 00:43:1615716 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215717 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415718
wezca1070932016-05-26 20:30:5215719 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415720 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15721
15722 std::string response_data;
bnc691fda62016-08-12 00:43:1615723 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115724 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415725 EXPECT_EQ("hello world", response_data);
15726}
15727
15728// This test makes sure the retry logic doesn't trigger when reading an error
15729// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115730TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415731 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915732 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415733 MockWrite data_writes[] = {
15734 MockWrite("GET / HTTP/1.1\r\n"
15735 "Host: www.foo.com\r\n"
15736 "Connection: keep-alive\r\n\r\n"),
15737 MockWrite("POST / HTTP/1.1\r\n"
15738 "Host: www.foo.com\r\n"
15739 "Connection: keep-alive\r\n"
15740 "Content-Length: 3\r\n\r\n"),
15741 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15742 };
15743
15744 MockRead data_reads[] = {
15745 MockRead("HTTP/1.1 200 Peachy\r\n"
15746 "Content-Length: 14\r\n\r\n"),
15747 MockRead("first response"),
15748 MockRead("HTTP/1.1 400 Not OK\r\n"
15749 "Content-Length: 15\r\n\r\n"),
15750 MockRead("second response"),
15751 MockRead(SYNCHRONOUS, OK),
15752 };
15753 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15754 arraysize(data_writes));
15755 session_deps_.socket_factory->AddSocketDataProvider(&data);
15756
15757 TestCompletionCallback callback;
15758 HttpRequestInfo request1;
15759 request1.method = "GET";
15760 request1.url = GURL("http://www.foo.com/");
15761 request1.load_flags = 0;
15762
bnc87dcefc2017-05-25 12:47:5815763 auto trans1 =
15764 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015765 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115766 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415767
15768 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115769 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415770
15771 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215772 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415773
wezca1070932016-05-26 20:30:5215774 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415775 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15776
15777 std::string response_data1;
15778 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115779 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415780 EXPECT_EQ("first response", response_data1);
15781 // Delete the transaction to release the socket back into the socket pool.
15782 trans1.reset();
15783
danakj1fd259a02016-04-16 03:17:0915784 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215785 element_readers.push_back(
bnc87dcefc2017-05-25 12:47:5815786 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215787 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415788
15789 HttpRequestInfo request2;
15790 request2.method = "POST";
15791 request2.url = GURL("http://www.foo.com/");
15792 request2.upload_data_stream = &upload_data_stream;
15793 request2.load_flags = 0;
15794
bnc691fda62016-08-12 00:43:1615795 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015796 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415798
15799 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115800 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415801
bnc691fda62016-08-12 00:43:1615802 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215803 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415804
wezca1070932016-05-26 20:30:5215805 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415806 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15807
15808 std::string response_data2;
bnc691fda62016-08-12 00:43:1615809 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115810 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415811 EXPECT_EQ("second response", response_data2);
15812}
15813
bncd16676a2016-07-20 16:23:0115814TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415815 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915816 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215817 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715818 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215819 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415820
15821 HttpRequestInfo request;
15822 request.method = "POST";
15823 request.url = GURL("http://www.foo.com/");
15824 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415825
danakj1fd259a02016-04-16 03:17:0915826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415828 // Send headers successfully, but get an error while sending the body.
15829 MockWrite data_writes[] = {
15830 MockWrite("POST / HTTP/1.1\r\n"
15831 "Host: www.foo.com\r\n"
15832 "Connection: keep-alive\r\n"
15833 "Content-Length: 3\r\n\r\n"
15834 "fo"),
15835 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15836 };
15837
15838 MockRead data_reads[] = {
15839 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15840 MockRead("hello world"),
15841 MockRead(SYNCHRONOUS, OK),
15842 };
15843 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15844 arraysize(data_writes));
15845 session_deps_.socket_factory->AddSocketDataProvider(&data);
15846
15847 TestCompletionCallback callback;
15848
tfarina42834112016-09-22 13:38:2015849 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115850 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415851
15852 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115853 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415854
bnc691fda62016-08-12 00:43:1615855 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215856 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415857
wezca1070932016-05-26 20:30:5215858 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415859 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15860
15861 std::string response_data;
bnc691fda62016-08-12 00:43:1615862 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115863 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415864 EXPECT_EQ("hello world", response_data);
15865}
15866
15867// This tests the more common case than the previous test, where headers and
15868// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115869TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715870 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415871
15872 HttpRequestInfo request;
15873 request.method = "POST";
15874 request.url = GURL("http://www.foo.com/");
15875 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415876
danakj1fd259a02016-04-16 03:17:0915877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415879 // Send headers successfully, but get an error while sending the body.
15880 MockWrite data_writes[] = {
15881 MockWrite("POST / HTTP/1.1\r\n"
15882 "Host: www.foo.com\r\n"
15883 "Connection: keep-alive\r\n"
15884 "Transfer-Encoding: chunked\r\n\r\n"),
15885 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15886 };
15887
15888 MockRead data_reads[] = {
15889 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15890 MockRead("hello world"),
15891 MockRead(SYNCHRONOUS, OK),
15892 };
15893 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15894 arraysize(data_writes));
15895 session_deps_.socket_factory->AddSocketDataProvider(&data);
15896
15897 TestCompletionCallback callback;
15898
tfarina42834112016-09-22 13:38:2015899 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415901 // Make sure the headers are sent before adding a chunk. This ensures that
15902 // they can't be merged with the body in a single send. Not currently
15903 // necessary since a chunked body is never merged with headers, but this makes
15904 // the test more future proof.
15905 base::RunLoop().RunUntilIdle();
15906
mmenkecbc2b712014-10-09 20:29:0715907 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415908
15909 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115910 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415911
bnc691fda62016-08-12 00:43:1615912 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215913 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415914
wezca1070932016-05-26 20:30:5215915 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415916 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15917
15918 std::string response_data;
bnc691fda62016-08-12 00:43:1615919 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115920 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415921 EXPECT_EQ("hello world", response_data);
15922}
15923
bncd16676a2016-07-20 16:23:0115924TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915925 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215926 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715927 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215928 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415929
15930 HttpRequestInfo request;
15931 request.method = "POST";
15932 request.url = GURL("http://www.foo.com/");
15933 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415934
danakj1fd259a02016-04-16 03:17:0915935 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615936 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415937
15938 MockWrite data_writes[] = {
15939 MockWrite("POST / HTTP/1.1\r\n"
15940 "Host: www.foo.com\r\n"
15941 "Connection: keep-alive\r\n"
15942 "Content-Length: 3\r\n\r\n"),
15943 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15944 };
15945
15946 MockRead data_reads[] = {
15947 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15948 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15949 MockRead("hello world"),
15950 MockRead(SYNCHRONOUS, OK),
15951 };
15952 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15953 arraysize(data_writes));
15954 session_deps_.socket_factory->AddSocketDataProvider(&data);
15955
15956 TestCompletionCallback callback;
15957
tfarina42834112016-09-22 13:38:2015958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415960
15961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115962 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415963
bnc691fda62016-08-12 00:43:1615964 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215965 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415966
wezca1070932016-05-26 20:30:5215967 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415968 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15969
15970 std::string response_data;
bnc691fda62016-08-12 00:43:1615971 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115972 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415973 EXPECT_EQ("hello world", response_data);
15974}
15975
bncd16676a2016-07-20 16:23:0115976TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915977 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215978 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715979 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215980 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415981
15982 HttpRequestInfo request;
15983 request.method = "POST";
15984 request.url = GURL("http://www.foo.com/");
15985 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415986
danakj1fd259a02016-04-16 03:17:0915987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415989 // Send headers successfully, but get an error while sending the body.
15990 MockWrite data_writes[] = {
15991 MockWrite("POST / HTTP/1.1\r\n"
15992 "Host: www.foo.com\r\n"
15993 "Connection: keep-alive\r\n"
15994 "Content-Length: 3\r\n\r\n"),
15995 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15996 };
15997
15998 MockRead data_reads[] = {
15999 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16000 MockRead("hello world"),
16001 MockRead(SYNCHRONOUS, OK),
16002 };
16003 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16004 arraysize(data_writes));
16005 session_deps_.socket_factory->AddSocketDataProvider(&data);
16006
16007 TestCompletionCallback callback;
16008
tfarina42834112016-09-22 13:38:2016009 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416011
16012 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116013 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416014}
16015
bncd16676a2016-07-20 16:23:0116016TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416017 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916018 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216019 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716020 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216021 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416022
16023 HttpRequestInfo request;
16024 request.method = "POST";
16025 request.url = GURL("http://www.foo.com/");
16026 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416027
danakj1fd259a02016-04-16 03:17:0916028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416030 // Send headers successfully, but get an error while sending the body.
16031 MockWrite data_writes[] = {
16032 MockWrite("POST / HTTP/1.1\r\n"
16033 "Host: www.foo.com\r\n"
16034 "Connection: keep-alive\r\n"
16035 "Content-Length: 3\r\n\r\n"),
16036 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16037 };
16038
16039 MockRead data_reads[] = {
16040 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16041 MockRead("HTTP/1.0 302 Redirect\r\n"),
16042 MockRead("Location: http://somewhere-else.com/\r\n"),
16043 MockRead("Content-Length: 0\r\n\r\n"),
16044 MockRead(SYNCHRONOUS, OK),
16045 };
16046 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16047 arraysize(data_writes));
16048 session_deps_.socket_factory->AddSocketDataProvider(&data);
16049
16050 TestCompletionCallback callback;
16051
tfarina42834112016-09-22 13:38:2016052 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116053 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416054
16055 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116056 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416057}
16058
bncd16676a2016-07-20 16:23:0116059TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916060 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216061 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716062 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216063 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416064
16065 HttpRequestInfo request;
16066 request.method = "POST";
16067 request.url = GURL("http://www.foo.com/");
16068 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416069
danakj1fd259a02016-04-16 03:17:0916070 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416072 // Send headers successfully, but get an error while sending the body.
16073 MockWrite data_writes[] = {
16074 MockWrite("POST / HTTP/1.1\r\n"
16075 "Host: www.foo.com\r\n"
16076 "Connection: keep-alive\r\n"
16077 "Content-Length: 3\r\n\r\n"),
16078 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16079 };
16080
16081 MockRead data_reads[] = {
16082 MockRead("HTTP 0.9 rocks!"),
16083 MockRead(SYNCHRONOUS, OK),
16084 };
16085 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16086 arraysize(data_writes));
16087 session_deps_.socket_factory->AddSocketDataProvider(&data);
16088
16089 TestCompletionCallback callback;
16090
tfarina42834112016-09-22 13:38:2016091 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416093
16094 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116095 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416096}
16097
bncd16676a2016-07-20 16:23:0116098TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916099 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216100 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716101 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216102 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416103
16104 HttpRequestInfo request;
16105 request.method = "POST";
16106 request.url = GURL("http://www.foo.com/");
16107 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416108
danakj1fd259a02016-04-16 03:17:0916109 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616110 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416111 // Send headers successfully, but get an error while sending the body.
16112 MockWrite data_writes[] = {
16113 MockWrite("POST / HTTP/1.1\r\n"
16114 "Host: www.foo.com\r\n"
16115 "Connection: keep-alive\r\n"
16116 "Content-Length: 3\r\n\r\n"),
16117 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16118 };
16119
16120 MockRead data_reads[] = {
16121 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16122 MockRead(SYNCHRONOUS, OK),
16123 };
16124 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16125 arraysize(data_writes));
16126 session_deps_.socket_factory->AddSocketDataProvider(&data);
16127
16128 TestCompletionCallback callback;
16129
tfarina42834112016-09-22 13:38:2016130 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116131 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416132
16133 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116134 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416135}
16136
Adam Rice425cf122015-01-19 06:18:2416137// Verify that proxy headers are not sent to the destination server when
16138// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116139TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416140 HttpRequestInfo request;
16141 request.method = "GET";
bncce36dca22015-04-21 22:11:2316142 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416143 AddWebSocketHeaders(&request.extra_headers);
16144
16145 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316146 session_deps_.proxy_service =
16147 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416148
danakj1fd259a02016-04-16 03:17:0916149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416150
16151 // Since a proxy is configured, try to establish a tunnel.
16152 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716153 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16154 "Host: www.example.org:443\r\n"
16155 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416156
16157 // After calling trans->RestartWithAuth(), this is the request we should
16158 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716159 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16160 "Host: www.example.org:443\r\n"
16161 "Proxy-Connection: keep-alive\r\n"
16162 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416163
rsleevidb16bb02015-11-12 23:47:1716164 MockWrite("GET / HTTP/1.1\r\n"
16165 "Host: www.example.org\r\n"
16166 "Connection: Upgrade\r\n"
16167 "Upgrade: websocket\r\n"
16168 "Origin: http://www.example.org\r\n"
16169 "Sec-WebSocket-Version: 13\r\n"
16170 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416171 };
16172
16173 // The proxy responds to the connect with a 407, using a persistent
16174 // connection.
16175 MockRead data_reads[] = {
16176 // No credentials.
16177 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16178 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416179 MockRead("Content-Length: 0\r\n"),
16180 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416181
16182 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16183
16184 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16185 MockRead("Upgrade: websocket\r\n"),
16186 MockRead("Connection: Upgrade\r\n"),
16187 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16188 };
16189
16190 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16191 arraysize(data_writes));
16192 session_deps_.socket_factory->AddSocketDataProvider(&data);
16193 SSLSocketDataProvider ssl(ASYNC, OK);
16194 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16195
bnc87dcefc2017-05-25 12:47:5816196 auto trans =
16197 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416198 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16199 trans->SetWebSocketHandshakeStreamCreateHelper(
16200 &websocket_stream_create_helper);
16201
16202 {
16203 TestCompletionCallback callback;
16204
tfarina42834112016-09-22 13:38:2016205 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416207
16208 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116209 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416210 }
16211
16212 const HttpResponseInfo* response = trans->GetResponseInfo();
16213 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216214 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416215 EXPECT_EQ(407, response->headers->response_code());
16216
16217 {
16218 TestCompletionCallback callback;
16219
16220 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16221 callback.callback());
robpercival214763f2016-07-01 23:27:0116222 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416223
16224 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116225 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416226 }
16227
16228 response = trans->GetResponseInfo();
16229 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216230 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416231
16232 EXPECT_EQ(101, response->headers->response_code());
16233
16234 trans.reset();
16235 session->CloseAllConnections();
16236}
16237
16238// Verify that proxy headers are not sent to the destination server when
16239// establishing a tunnel for an insecure WebSocket connection.
16240// This requires the authentication info to be injected into the auth cache
16241// due to crbug.com/395064
16242// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116243TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416244 HttpRequestInfo request;
16245 request.method = "GET";
bncce36dca22015-04-21 22:11:2316246 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416247 AddWebSocketHeaders(&request.extra_headers);
16248
16249 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316250 session_deps_.proxy_service =
16251 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416252
danakj1fd259a02016-04-16 03:17:0916253 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416254
16255 MockWrite data_writes[] = {
16256 // Try to establish a tunnel for the WebSocket connection, with
16257 // credentials. Because WebSockets have a separate set of socket pools,
16258 // they cannot and will not use the same TCP/IP connection as the
16259 // preflight HTTP request.
16260 MockWrite(
bncce36dca22015-04-21 22:11:2316261 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16262 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416263 "Proxy-Connection: keep-alive\r\n"
16264 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16265
16266 MockWrite(
16267 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316268 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416269 "Connection: Upgrade\r\n"
16270 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316271 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416272 "Sec-WebSocket-Version: 13\r\n"
16273 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16274 };
16275
16276 MockRead data_reads[] = {
16277 // HTTP CONNECT with credentials.
16278 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16279
16280 // WebSocket connection established inside tunnel.
16281 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16282 MockRead("Upgrade: websocket\r\n"),
16283 MockRead("Connection: Upgrade\r\n"),
16284 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16285 };
16286
16287 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16288 arraysize(data_writes));
16289 session_deps_.socket_factory->AddSocketDataProvider(&data);
16290
16291 session->http_auth_cache()->Add(
16292 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16293 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16294
bnc87dcefc2017-05-25 12:47:5816295 auto trans =
16296 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416297 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16298 trans->SetWebSocketHandshakeStreamCreateHelper(
16299 &websocket_stream_create_helper);
16300
16301 TestCompletionCallback callback;
16302
tfarina42834112016-09-22 13:38:2016303 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416305
16306 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116307 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416308
16309 const HttpResponseInfo* response = trans->GetResponseInfo();
16310 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216311 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416312
16313 EXPECT_EQ(101, response->headers->response_code());
16314
16315 trans.reset();
16316 session->CloseAllConnections();
16317}
16318
bncd16676a2016-07-20 16:23:0116319TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916320 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216321 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716322 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216323 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216324
16325 HttpRequestInfo request;
16326 request.method = "POST";
16327 request.url = GURL("http://www.foo.com/");
16328 request.upload_data_stream = &upload_data_stream;
16329
danakj1fd259a02016-04-16 03:17:0916330 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216332 MockWrite data_writes[] = {
16333 MockWrite("POST / HTTP/1.1\r\n"
16334 "Host: www.foo.com\r\n"
16335 "Connection: keep-alive\r\n"
16336 "Content-Length: 3\r\n\r\n"),
16337 MockWrite("foo"),
16338 };
16339
16340 MockRead data_reads[] = {
16341 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16342 MockRead(SYNCHRONOUS, OK),
16343 };
16344 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16345 arraysize(data_writes));
16346 session_deps_.socket_factory->AddSocketDataProvider(&data);
16347
16348 TestCompletionCallback callback;
16349
16350 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016351 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116352 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216353
16354 std::string response_data;
bnc691fda62016-08-12 00:43:1616355 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216356
16357 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616358 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216359 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616360 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216361}
16362
bncd16676a2016-07-20 16:23:0116363TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916364 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216365 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716366 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216367 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216368
16369 HttpRequestInfo request;
16370 request.method = "POST";
16371 request.url = GURL("http://www.foo.com/");
16372 request.upload_data_stream = &upload_data_stream;
16373
danakj1fd259a02016-04-16 03:17:0916374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216376 MockWrite data_writes[] = {
16377 MockWrite("POST / HTTP/1.1\r\n"
16378 "Host: www.foo.com\r\n"
16379 "Connection: keep-alive\r\n"
16380 "Content-Length: 3\r\n\r\n"),
16381 MockWrite("foo"),
16382 };
16383
16384 MockRead data_reads[] = {
16385 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16386 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16387 MockRead(SYNCHRONOUS, OK),
16388 };
16389 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16390 arraysize(data_writes));
16391 session_deps_.socket_factory->AddSocketDataProvider(&data);
16392
16393 TestCompletionCallback callback;
16394
16395 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016396 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116397 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216398
16399 std::string response_data;
bnc691fda62016-08-12 00:43:1616400 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216401
16402 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616403 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216404 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616405 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216406}
16407
bncd16676a2016-07-20 16:23:0116408TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216409 ChunkedUploadDataStream upload_data_stream(0);
16410
16411 HttpRequestInfo request;
16412 request.method = "POST";
16413 request.url = GURL("http://www.foo.com/");
16414 request.upload_data_stream = &upload_data_stream;
16415
danakj1fd259a02016-04-16 03:17:0916416 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216418 // Send headers successfully, but get an error while sending the body.
16419 MockWrite data_writes[] = {
16420 MockWrite("POST / HTTP/1.1\r\n"
16421 "Host: www.foo.com\r\n"
16422 "Connection: keep-alive\r\n"
16423 "Transfer-Encoding: chunked\r\n\r\n"),
16424 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16425 };
16426
16427 MockRead data_reads[] = {
16428 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16429 MockRead(SYNCHRONOUS, OK),
16430 };
16431 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16432 arraysize(data_writes));
16433 session_deps_.socket_factory->AddSocketDataProvider(&data);
16434
16435 TestCompletionCallback callback;
16436
16437 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016438 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216439
16440 base::RunLoop().RunUntilIdle();
16441 upload_data_stream.AppendData("f", 1, false);
16442
16443 base::RunLoop().RunUntilIdle();
16444 upload_data_stream.AppendData("oo", 2, true);
16445
robpercival214763f2016-07-01 23:27:0116446 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216447
16448 std::string response_data;
bnc691fda62016-08-12 00:43:1616449 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216450
16451 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616452 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216453 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616454 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216455}
16456
rdsmith1d343be52016-10-21 20:37:5016457// Confirm that transactions whose throttle is created in (and stays in)
16458// the unthrottled state are not blocked.
16459TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16460 TestNetworkStreamThrottler* throttler(nullptr);
16461 std::unique_ptr<HttpNetworkSession> session(
16462 CreateSessionWithThrottler(&session_deps_, &throttler));
16463
16464 // Send a simple request and make sure it goes through.
16465 HttpRequestInfo request;
16466 request.method = "GET";
16467 request.url = GURL("http://www.example.org/");
16468
bnc87dcefc2017-05-25 12:47:5816469 auto trans =
16470 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016471
16472 MockWrite data_writes[] = {
16473 MockWrite("GET / HTTP/1.1\r\n"
16474 "Host: www.example.org\r\n"
16475 "Connection: keep-alive\r\n\r\n"),
16476 };
16477 MockRead data_reads[] = {
16478 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16479 MockRead(SYNCHRONOUS, OK),
16480 };
16481 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16482 arraysize(data_writes));
16483 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16484
16485 TestCompletionCallback callback;
16486 trans->Start(&request, callback.callback(), NetLogWithSource());
16487 EXPECT_EQ(OK, callback.WaitForResult());
16488}
16489
16490// Confirm requests can be blocked by a throttler, and are resumed
16491// when the throttle is unblocked.
16492TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16493 TestNetworkStreamThrottler* throttler(nullptr);
16494 std::unique_ptr<HttpNetworkSession> session(
16495 CreateSessionWithThrottler(&session_deps_, &throttler));
16496
16497 // Send a simple request and make sure it goes through.
16498 HttpRequestInfo request;
16499 request.method = "GET";
16500 request.url = GURL("http://www.example.org/");
16501
16502 MockWrite data_writes[] = {
16503 MockWrite("GET / HTTP/1.1\r\n"
16504 "Host: www.example.org\r\n"
16505 "Connection: keep-alive\r\n\r\n"),
16506 };
16507 MockRead data_reads[] = {
16508 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16509 MockRead(SYNCHRONOUS, OK),
16510 };
16511 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16512 arraysize(data_writes));
16513 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16514
16515 // Start a request that will be throttled at start; confirm it
16516 // doesn't complete.
16517 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816518 auto trans =
16519 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016520
16521 TestCompletionCallback callback;
16522 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16523 EXPECT_EQ(ERR_IO_PENDING, rv);
16524
16525 base::RunLoop().RunUntilIdle();
16526 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16527 EXPECT_FALSE(callback.have_result());
16528
16529 // Confirm the request goes on to complete when unthrottled.
16530 throttler->UnthrottleAllRequests();
16531 base::RunLoop().RunUntilIdle();
16532 ASSERT_TRUE(callback.have_result());
16533 EXPECT_EQ(OK, callback.WaitForResult());
16534}
16535
16536// Destroy a request while it's throttled.
16537TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16538 TestNetworkStreamThrottler* throttler(nullptr);
16539 std::unique_ptr<HttpNetworkSession> session(
16540 CreateSessionWithThrottler(&session_deps_, &throttler));
16541
16542 // Send a simple request and make sure it goes through.
16543 HttpRequestInfo request;
16544 request.method = "GET";
16545 request.url = GURL("http://www.example.org/");
16546
16547 MockWrite data_writes[] = {
16548 MockWrite("GET / HTTP/1.1\r\n"
16549 "Host: www.example.org\r\n"
16550 "Connection: keep-alive\r\n\r\n"),
16551 };
16552 MockRead data_reads[] = {
16553 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16554 MockRead(SYNCHRONOUS, OK),
16555 };
16556 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16557 arraysize(data_writes));
16558 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16559
16560 // Start a request that will be throttled at start; confirm it
16561 // doesn't complete.
16562 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816563 auto trans =
16564 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016565
16566 TestCompletionCallback callback;
16567 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16568 EXPECT_EQ(ERR_IO_PENDING, rv);
16569
16570 base::RunLoop().RunUntilIdle();
16571 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16572 EXPECT_FALSE(callback.have_result());
16573
16574 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16575 trans.reset();
16576 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16577}
16578
16579// Confirm the throttler receives SetPriority calls.
16580TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16581 TestNetworkStreamThrottler* throttler(nullptr);
16582 std::unique_ptr<HttpNetworkSession> session(
16583 CreateSessionWithThrottler(&session_deps_, &throttler));
16584
16585 // Send a simple request and make sure it goes through.
16586 HttpRequestInfo request;
16587 request.method = "GET";
16588 request.url = GURL("http://www.example.org/");
16589
16590 MockWrite data_writes[] = {
16591 MockWrite("GET / HTTP/1.1\r\n"
16592 "Host: www.example.org\r\n"
16593 "Connection: keep-alive\r\n\r\n"),
16594 };
16595 MockRead data_reads[] = {
16596 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16597 MockRead(SYNCHRONOUS, OK),
16598 };
16599 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16600 arraysize(data_writes));
16601 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16602
16603 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816604 auto trans = base::MakeUnique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016605 // Start the transaction to associate a throttle with it.
16606 TestCompletionCallback callback;
16607 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16608 EXPECT_EQ(ERR_IO_PENDING, rv);
16609
16610 EXPECT_EQ(0, throttler->num_set_priority_calls());
16611 trans->SetPriority(LOW);
16612 EXPECT_EQ(1, throttler->num_set_priority_calls());
16613 EXPECT_EQ(LOW, throttler->last_priority_set());
16614
16615 throttler->UnthrottleAllRequests();
16616 base::RunLoop().RunUntilIdle();
16617 ASSERT_TRUE(callback.have_result());
16618 EXPECT_EQ(OK, callback.WaitForResult());
16619}
16620
16621// Confirm that unthrottling from a SetPriority call by the
16622// throttler works properly.
16623TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16624 TestNetworkStreamThrottler* throttler(nullptr);
16625 std::unique_ptr<HttpNetworkSession> session(
16626 CreateSessionWithThrottler(&session_deps_, &throttler));
16627
16628 // Send a simple request and make sure it goes through.
16629 HttpRequestInfo request;
16630 request.method = "GET";
16631 request.url = GURL("http://www.example.org/");
16632
16633 MockWrite data_writes[] = {
16634 MockWrite("GET / HTTP/1.1\r\n"
16635 "Host: www.example.org\r\n"
16636 "Connection: keep-alive\r\n\r\n"),
16637 };
16638 MockRead data_reads[] = {
16639 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16640 MockRead(SYNCHRONOUS, OK),
16641 };
16642 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16643 arraysize(data_writes));
16644 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16645
16646 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16647 data_writes, arraysize(data_writes));
16648 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16649
16650 // Start a request that will be throttled at start; confirm it
16651 // doesn't complete.
16652 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816653 auto trans =
16654 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016655
16656 TestCompletionCallback callback;
16657 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16658 EXPECT_EQ(ERR_IO_PENDING, rv);
16659
16660 base::RunLoop().RunUntilIdle();
16661 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16662 EXPECT_FALSE(callback.have_result());
16663
16664 // Create a new request, call SetPriority on it to unthrottle,
16665 // and make sure that allows the original request to complete.
bnc87dcefc2017-05-25 12:47:5816666 auto trans1 = base::MakeUnique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5016667 throttler->set_priority_change_closure(
16668 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16669 base::Unretained(throttler)));
16670
16671 // Start the transaction to associate a throttle with it.
16672 TestCompletionCallback callback1;
16673 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16674 EXPECT_EQ(ERR_IO_PENDING, rv);
16675
16676 trans1->SetPriority(IDLE);
16677
16678 base::RunLoop().RunUntilIdle();
16679 ASSERT_TRUE(callback.have_result());
16680 EXPECT_EQ(OK, callback.WaitForResult());
16681 ASSERT_TRUE(callback1.have_result());
16682 EXPECT_EQ(OK, callback1.WaitForResult());
16683}
16684
16685// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5816686void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5016687
16688// Confirm that destroying a transaction from a SetPriority call by the
16689// throttler works properly.
16690TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16691 TestNetworkStreamThrottler* throttler(nullptr);
16692 std::unique_ptr<HttpNetworkSession> session(
16693 CreateSessionWithThrottler(&session_deps_, &throttler));
16694
16695 // Send a simple request and make sure it goes through.
16696 HttpRequestInfo request;
16697 request.method = "GET";
16698 request.url = GURL("http://www.example.org/");
16699
16700 MockWrite data_writes[] = {
16701 MockWrite("GET / HTTP/1.1\r\n"
16702 "Host: www.example.org\r\n"
16703 "Connection: keep-alive\r\n\r\n"),
16704 };
16705 MockRead data_reads[] = {
16706 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16707 MockRead(SYNCHRONOUS, OK),
16708 };
16709 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16710 arraysize(data_writes));
16711 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16712
16713 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16714 data_writes, arraysize(data_writes));
16715 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16716
16717 // Start a request that will be throttled at start; confirm it
16718 // doesn't complete.
16719 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816720 auto trans =
16721 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016722
16723 TestCompletionCallback callback;
16724 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16725 EXPECT_EQ(ERR_IO_PENDING, rv);
16726
16727 base::RunLoop().RunUntilIdle();
16728 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16729 EXPECT_FALSE(callback.have_result());
16730
16731 // Arrange for the set priority call on the above transaction to delete
16732 // the transaction.
bnc87dcefc2017-05-25 12:47:5816733 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5016734 throttler->set_priority_change_closure(
16735 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16736
16737 // Call it and check results (partially a "doesn't crash" test).
16738 trans_ptr->SetPriority(IDLE);
16739 trans_ptr = nullptr; // No longer a valid pointer.
16740
16741 base::RunLoop().RunUntilIdle();
16742 ASSERT_FALSE(callback.have_result());
16743}
16744
nharperb7441ef2016-01-25 23:54:1416745#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116746TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416747 const std::string https_url = "https://www.example.com";
16748 HttpRequestInfo request;
16749 request.url = GURL(https_url);
16750 request.method = "GET";
16751
16752 SSLSocketDataProvider ssl(ASYNC, OK);
16753 ssl.token_binding_negotiated = true;
16754 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616755 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16757
bnc42331402016-07-25 13:36:1516758 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116759 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16760 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416761 MockRead(ASYNC, ERR_IO_PENDING)};
16762 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16763 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5816764 session_deps_.channel_id_service =
16765 base::MakeUnique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0916766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416767
16768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16769 TestCompletionCallback callback;
16770 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016771 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1016772
16773 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416774
16775 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16776 HttpRequestHeaders headers;
16777 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16778 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16779}
16780#endif // !defined(OS_IOS)
16781
eustasc7d27da2017-04-06 10:33:2016782void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
16783 const std::string& accept_encoding,
16784 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0316785 const std::string& location,
eustasc7d27da2017-04-06 10:33:2016786 bool should_match) {
16787 HttpRequestInfo request;
16788 request.method = "GET";
16789 request.url = GURL("http://www.foo.com/");
16790 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
16791 accept_encoding);
16792
16793 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
16794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16795 // Send headers successfully, but get an error while sending the body.
16796 MockWrite data_writes[] = {
16797 MockWrite("GET / HTTP/1.1\r\n"
16798 "Host: www.foo.com\r\n"
16799 "Connection: keep-alive\r\n"
16800 "Accept-Encoding: "),
16801 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
16802 };
16803
sky50576f32017-05-01 19:28:0316804 std::string response_code = "200 OK";
16805 std::string extra;
16806 if (!location.empty()) {
16807 response_code = "301 Redirect\r\nLocation: ";
16808 response_code.append(location);
16809 }
16810
eustasc7d27da2017-04-06 10:33:2016811 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0316812 MockRead("HTTP/1.0 "),
16813 MockRead(response_code.data()),
16814 MockRead("\r\nContent-Encoding: "),
16815 MockRead(content_encoding.data()),
16816 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2016817 MockRead(SYNCHRONOUS, OK),
16818 };
16819 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16820 arraysize(data_writes));
16821 session_deps->socket_factory->AddSocketDataProvider(&data);
16822
16823 TestCompletionCallback callback;
16824
16825 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16827
16828 rv = callback.WaitForResult();
16829 if (should_match) {
16830 EXPECT_THAT(rv, IsOk());
16831 } else {
16832 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
16833 }
16834}
16835
16836TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0316837 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2016838}
16839
16840TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0316841 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
16842 true);
eustasc7d27da2017-04-06 10:33:2016843}
16844
16845TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
16846 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0316847 "", false);
16848}
16849
16850TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
16851 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
16852 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2016853}
16854
xunjieli96f2a402017-06-05 17:24:2716855TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
16856 ProxyConfig proxy_config;
16857 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
16858 proxy_config.set_pac_mandatory(true);
16859 MockAsyncProxyResolver resolver;
16860 session_deps_.proxy_service.reset(new ProxyService(
16861 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
16862 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
16863
16864 HttpRequestInfo request;
16865 request.method = "GET";
16866 request.url = GURL("http://www.example.org/");
16867
16868 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16870
16871 TestCompletionCallback callback;
16872
16873 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16875 EXPECT_THAT(callback.WaitForResult(),
16876 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
16877}
16878
16879TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
16880 ProxyConfig proxy_config;
16881 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
16882 proxy_config.set_pac_mandatory(true);
16883 MockAsyncProxyResolverFactory* proxy_resolver_factory =
16884 new MockAsyncProxyResolverFactory(false);
16885 MockAsyncProxyResolver resolver;
16886 session_deps_.proxy_service.reset(
16887 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
16888 base::WrapUnique(proxy_resolver_factory), nullptr));
16889 HttpRequestInfo request;
16890 request.method = "GET";
16891 request.url = GURL("http://www.example.org/");
16892
16893 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16894 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16895
16896 TestCompletionCallback callback;
16897 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16899
16900 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
16901 ERR_FAILED, &resolver);
16902 EXPECT_THAT(callback.WaitForResult(),
16903 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
16904}
16905
16906TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
16907 session_deps_.proxy_service =
16908 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
16909 session_deps_.enable_quic = false;
16910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16911
16912 HttpRequestInfo request;
16913 request.method = "GET";
16914 request.url = GURL("http://www.example.org/");
16915
16916 TestCompletionCallback callback;
16917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16918 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16920
16921 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
16922}
16923
[email protected]89ceba9a2009-03-21 03:46:0616924} // namespace net