blob: b5eff6c900604bd59c7b2fbdcc890d0e435b1091 [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 */)
rkaplowd90695c2015-03-25 22:12:41736 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50737}
[email protected]2df19bb2010-08-25 20:13:46738
[email protected]007b3f82013-04-09 08:46:45739template <>
[email protected]e60e47a2010-07-14 03:37:18740CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21741 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34742 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45743 : SSLClientSocketPool(0,
744 0,
[email protected]007b3f82013-04-09 08:46:45745 cert_verifier,
746 NULL,
747 NULL,
[email protected]284303b62013-11-28 15:11:54748 NULL,
eranm6571b2b2014-12-03 15:53:23749 NULL,
[email protected]007b3f82013-04-09 08:46:45750 std::string(),
751 NULL,
752 NULL,
753 NULL,
754 NULL,
755 NULL,
[email protected]8e458552014-08-05 00:02:15756 NULL) {
757}
[email protected]2227c692010-05-04 15:36:11758
[email protected]231d5a32008-09-13 00:45:27759//-----------------------------------------------------------------------------
760
[email protected]79cb5c12011-09-12 13:12:04761// Helper functions for validating that AuthChallengeInfo's are correctly
762// configured for common cases.
763bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
764 if (!auth_challenge)
765 return false;
766 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43767 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04768 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19769 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04770 return true;
771}
772
773bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
774 if (!auth_challenge)
775 return false;
776 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43777 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
778 EXPECT_EQ("MyRealm1", auth_challenge->realm);
779 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
780 return true;
781}
782
783bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
784 if (!auth_challenge)
785 return false;
786 EXPECT_TRUE(auth_challenge->is_proxy);
787 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04788 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19789 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04790 return true;
791}
792
793bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
794 if (!auth_challenge)
795 return false;
796 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43797 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04798 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19799 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04800 return true;
801}
802
thakis84dff942015-07-28 20:47:38803#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04804bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
805 if (!auth_challenge)
806 return false;
807 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43808 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04809 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19810 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04811 return true;
812}
thakis84dff942015-07-28 20:47:38813#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04814
[email protected]448d4ca52012-03-04 04:12:23815} // namespace
816
bncd16676a2016-07-20 16:23:01817TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09818 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16819 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27820}
821
bncd16676a2016-07-20 16:23:01822TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27823 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35824 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
825 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06826 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27827 };
[email protected]31a2bfe2010-02-09 08:03:39828 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
829 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01830 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27831 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
832 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22833 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
834 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47835 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59836
837 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27838}
839
840// Response with no status line.
bncd16676a2016-07-20 16:23:01841TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27842 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35843 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06844 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27845 };
[email protected]31a2bfe2010-02-09 08:03:39846 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
847 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41848 EXPECT_THAT(out.rv, IsOk());
849 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
850 EXPECT_EQ("hello world", out.response_data);
851 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
852 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27853}
854
mmenkea7da6da2016-09-01 21:56:52855// Response with no status line, and a weird port. Should fail by default.
856TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
857 MockRead data_reads[] = {
858 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
859 };
860
861 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
862 session_deps_.socket_factory->AddSocketDataProvider(&data);
863
864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
865
krasinc06a72a2016-12-21 03:42:46866 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58867 auto trans =
868 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52869
mmenkea7da6da2016-09-01 21:56:52870 request.method = "GET";
871 request.url = GURL("http://www.example.com:2000/");
872 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20873 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52874 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
875}
876
877// Response with no status line, and a weird port. Option to allow weird ports
878// enabled.
879TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
880 MockRead data_reads[] = {
881 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
882 };
883
884 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
885 session_deps_.socket_factory->AddSocketDataProvider(&data);
886 session_deps_.http_09_on_non_default_ports_enabled = true;
887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
888
krasinc06a72a2016-12-21 03:42:46889 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58890 auto trans =
891 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52892
mmenkea7da6da2016-09-01 21:56:52893 request.method = "GET";
894 request.url = GURL("http://www.example.com:2000/");
895 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20896 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52897 EXPECT_THAT(callback.GetResult(rv), IsOk());
898
899 const HttpResponseInfo* info = trans->GetResponseInfo();
900 ASSERT_TRUE(info->headers);
901 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
902
903 // Don't bother to read the body - that's verified elsewhere, important thing
904 // is that the option to allow HTTP/0.9 on non-default ports is respected.
905}
906
[email protected]231d5a32008-09-13 00:45:27907// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01908TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27909 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35910 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06911 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27912 };
[email protected]31a2bfe2010-02-09 08:03:39913 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
914 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01915 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27916 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
917 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22918 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
919 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27920}
921
922// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01923TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27924 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35925 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06926 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27927 };
[email protected]31a2bfe2010-02-09 08:03:39928 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
929 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01930 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27931 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
932 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22933 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
934 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27935}
936
937// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01938TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27939 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35940 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06941 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27942 };
[email protected]31a2bfe2010-02-09 08:03:39943 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
944 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41945 EXPECT_THAT(out.rv, IsOk());
946 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
947 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
948 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
949 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27950}
951
952// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01953TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27954 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35955 MockRead("\n"),
956 MockRead("\n"),
957 MockRead("Q"),
958 MockRead("J"),
959 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06960 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27961 };
[email protected]31a2bfe2010-02-09 08:03:39962 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
963 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01964 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27965 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
966 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22967 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
968 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27969}
970
971// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01972TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27973 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35974 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06975 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27976 };
[email protected]31a2bfe2010-02-09 08:03:39977 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
978 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41979 EXPECT_THAT(out.rv, IsOk());
980 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
981 EXPECT_EQ("HTT", out.response_data);
982 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
983 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52984}
985
[email protected]f9d44aa2008-09-23 23:57:17986// Simulate a 204 response, lacking a Content-Length header, sent over a
987// persistent connection. The response should still terminate since a 204
988// cannot have a response body.
bncd16676a2016-07-20 16:23:01989TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19990 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17991 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35992 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19993 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06994 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17995 };
[email protected]31a2bfe2010-02-09 08:03:39996 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
997 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01998 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17999 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1000 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221001 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1002 int64_t response_size = reads_size - strlen(junk);
1003 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171004}
1005
[email protected]0877e3d2009-10-17 22:29:571006// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011007TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191008 std::string final_chunk = "0\r\n\r\n";
1009 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1010 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571011 MockRead data_reads[] = {
1012 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1013 MockRead("5\r\nHello\r\n"),
1014 MockRead("1\r\n"),
1015 MockRead(" \r\n"),
1016 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191017 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061018 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571019 };
[email protected]31a2bfe2010-02-09 08:03:391020 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1021 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011022 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571023 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1024 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221025 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1026 int64_t response_size = reads_size - extra_data.size();
1027 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571028}
1029
[email protected]9fe44f52010-09-23 18:36:001030// Next tests deal with http://crbug.com/56344.
1031
bncd16676a2016-07-20 16:23:011032TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001033 MultipleContentLengthHeadersNoTransferEncoding) {
1034 MockRead data_reads[] = {
1035 MockRead("HTTP/1.1 200 OK\r\n"),
1036 MockRead("Content-Length: 10\r\n"),
1037 MockRead("Content-Length: 5\r\n\r\n"),
1038 };
1039 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1040 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011041 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001042}
1043
bncd16676a2016-07-20 16:23:011044TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041045 DuplicateContentLengthHeadersNoTransferEncoding) {
1046 MockRead data_reads[] = {
1047 MockRead("HTTP/1.1 200 OK\r\n"),
1048 MockRead("Content-Length: 5\r\n"),
1049 MockRead("Content-Length: 5\r\n\r\n"),
1050 MockRead("Hello"),
1051 };
1052 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1053 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041055 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1056 EXPECT_EQ("Hello", out.response_data);
1057}
1058
bncd16676a2016-07-20 16:23:011059TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041060 ComplexContentLengthHeadersNoTransferEncoding) {
1061 // More than 2 dupes.
1062 {
1063 MockRead data_reads[] = {
1064 MockRead("HTTP/1.1 200 OK\r\n"),
1065 MockRead("Content-Length: 5\r\n"),
1066 MockRead("Content-Length: 5\r\n"),
1067 MockRead("Content-Length: 5\r\n\r\n"),
1068 MockRead("Hello"),
1069 };
1070 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1071 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041073 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1074 EXPECT_EQ("Hello", out.response_data);
1075 }
1076 // HTTP/1.0
1077 {
1078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.0 200 OK\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n"),
1082 MockRead("Content-Length: 5\r\n\r\n"),
1083 MockRead("Hello"),
1084 };
1085 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1086 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011087 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041088 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1089 EXPECT_EQ("Hello", out.response_data);
1090 }
1091 // 2 dupes and one mismatched.
1092 {
1093 MockRead data_reads[] = {
1094 MockRead("HTTP/1.1 200 OK\r\n"),
1095 MockRead("Content-Length: 10\r\n"),
1096 MockRead("Content-Length: 10\r\n"),
1097 MockRead("Content-Length: 5\r\n\r\n"),
1098 };
1099 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1100 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011101 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041102 }
1103}
1104
bncd16676a2016-07-20 16:23:011105TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001106 MultipleContentLengthHeadersTransferEncoding) {
1107 MockRead data_reads[] = {
1108 MockRead("HTTP/1.1 200 OK\r\n"),
1109 MockRead("Content-Length: 666\r\n"),
1110 MockRead("Content-Length: 1337\r\n"),
1111 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1112 MockRead("5\r\nHello\r\n"),
1113 MockRead("1\r\n"),
1114 MockRead(" \r\n"),
1115 MockRead("5\r\nworld\r\n"),
1116 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061117 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001118 };
1119 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1120 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011121 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001122 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1123 EXPECT_EQ("Hello world", out.response_data);
1124}
1125
[email protected]1628fe92011-10-04 23:04:551126// Next tests deal with http://crbug.com/98895.
1127
1128// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011129TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551130 MockRead data_reads[] = {
1131 MockRead("HTTP/1.1 200 OK\r\n"),
1132 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1133 MockRead("Content-Length: 5\r\n\r\n"),
1134 MockRead("Hello"),
1135 };
1136 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1137 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011138 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551139 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1140 EXPECT_EQ("Hello", out.response_data);
1141}
1142
[email protected]54a9c6e52012-03-21 20:10:591143// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011144TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551145 MockRead data_reads[] = {
1146 MockRead("HTTP/1.1 200 OK\r\n"),
1147 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1148 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1149 MockRead("Content-Length: 5\r\n\r\n"),
1150 MockRead("Hello"),
1151 };
1152 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1153 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011154 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591155 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1156 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551157}
1158
1159// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011160TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551161 MockRead data_reads[] = {
1162 MockRead("HTTP/1.1 200 OK\r\n"),
1163 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1164 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1165 MockRead("Content-Length: 5\r\n\r\n"),
1166 MockRead("Hello"),
1167 };
1168 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1169 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011170 EXPECT_THAT(out.rv,
1171 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551172}
1173
[email protected]54a9c6e52012-03-21 20:10:591174// Checks that two identical Location headers result in no error.
1175// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011176TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551177 MockRead data_reads[] = {
1178 MockRead("HTTP/1.1 302 Redirect\r\n"),
1179 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591180 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551181 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061182 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551183 };
1184
1185 HttpRequestInfo request;
1186 request.method = "GET";
1187 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551188
danakj1fd259a02016-04-16 03:17:091189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551191
1192 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071193 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551194
[email protected]49639fa2011-12-20 23:22:411195 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551196
tfarina42834112016-09-22 13:38:201197 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011198 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551199
robpercival214763f2016-07-01 23:27:011200 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551201
bnc691fda62016-08-12 00:43:161202 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521203 ASSERT_TRUE(response);
1204 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551205 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1206 std::string url;
1207 EXPECT_TRUE(response->headers->IsRedirect(&url));
1208 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471209 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551210}
1211
[email protected]1628fe92011-10-04 23:04:551212// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011213TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551214 MockRead data_reads[] = {
1215 MockRead("HTTP/1.1 302 Redirect\r\n"),
1216 MockRead("Location: http://good.com/\r\n"),
1217 MockRead("Location: http://evil.com/\r\n"),
1218 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061219 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551220 };
1221 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1222 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011223 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551224}
1225
[email protected]ef0faf2e72009-03-05 23:27:231226// Do a request using the HEAD method. Verify that we don't try to read the
1227// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011228TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421229 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231230 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231231 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231232
danakj1fd259a02016-04-16 03:17:091233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091235 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161236 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091237 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1238 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271239
[email protected]ef0faf2e72009-03-05 23:27:231240 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131241 MockWrite("HEAD / HTTP/1.1\r\n"
1242 "Host: www.example.org\r\n"
1243 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231244 };
1245 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231246 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1247 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231248
mmenked39192ee2015-12-09 00:57:231249 // No response body because the test stops reading here.
1250 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231251 };
1252
[email protected]31a2bfe2010-02-09 08:03:391253 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1254 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071255 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231256
[email protected]49639fa2011-12-20 23:22:411257 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231258
tfarina42834112016-09-22 13:38:201259 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011260 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231261
1262 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011263 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231264
bnc691fda62016-08-12 00:43:161265 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521266 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231267
1268 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521269 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231270 EXPECT_EQ(1234, response->headers->GetContentLength());
1271 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471272 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091273 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1274 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231275
1276 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101277 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231278 bool has_server_header = response->headers->EnumerateHeader(
1279 &iter, "Server", &server_header);
1280 EXPECT_TRUE(has_server_header);
1281 EXPECT_EQ("Blah", server_header);
1282
1283 // Reading should give EOF right away, since there is no message body
1284 // (despite non-zero content-length).
1285 std::string response_data;
bnc691fda62016-08-12 00:43:161286 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011287 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231288 EXPECT_EQ("", response_data);
1289}
1290
bncd16676a2016-07-20 16:23:011291TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521293
1294 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351295 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1296 MockRead("hello"),
1297 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1298 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061299 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521300 };
[email protected]31a2bfe2010-02-09 08:03:391301 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071302 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521303
[email protected]0b0bf032010-09-21 18:08:501304 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521305 "hello", "world"
1306 };
1307
1308 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421309 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521310 request.method = "GET";
bncce36dca22015-04-21 22:11:231311 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521312
bnc691fda62016-08-12 00:43:161313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271314
[email protected]49639fa2011-12-20 23:22:411315 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521316
tfarina42834112016-09-22 13:38:201317 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521319
1320 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011321 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521322
bnc691fda62016-08-12 00:43:161323 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521324 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521325
wezca1070932016-05-26 20:30:521326 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251327 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471328 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521329
1330 std::string response_data;
bnc691fda62016-08-12 00:43:161331 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011332 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251333 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521334 }
1335}
1336
bncd16676a2016-07-20 16:23:011337TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091338 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221339 element_readers.push_back(
ricea2deef682016-09-09 08:04:071340 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221341 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271342
[email protected]1c773ea12009-04-28 19:58:421343 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521344 request.method = "POST";
1345 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271346 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521347
shivanishab9a143952016-09-19 17:23:411348 // Check the upload progress returned before initialization is correct.
1349 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1350 EXPECT_EQ(0u, progress.size());
1351 EXPECT_EQ(0u, progress.position());
1352
danakj1fd259a02016-04-16 03:17:091353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271355
initial.commit586acc5fe2008-07-26 22:42:521356 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351357 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1358 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1359 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061360 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521361 };
[email protected]31a2bfe2010-02-09 08:03:391362 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071363 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521364
[email protected]49639fa2011-12-20 23:22:411365 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521366
tfarina42834112016-09-22 13:38:201367 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521369
1370 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011371 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521372
bnc691fda62016-08-12 00:43:161373 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521374 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521375
wezca1070932016-05-26 20:30:521376 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251377 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521378
1379 std::string response_data;
bnc691fda62016-08-12 00:43:161380 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011381 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251382 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521383}
1384
[email protected]3a2d3662009-03-27 03:49:141385// This test is almost the same as Ignores100 above, but the response contains
1386// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571387// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011388TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421389 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141390 request.method = "GET";
1391 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141392
danakj1fd259a02016-04-16 03:17:091393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271395
[email protected]3a2d3662009-03-27 03:49:141396 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571397 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1398 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141399 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061400 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141401 };
[email protected]31a2bfe2010-02-09 08:03:391402 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071403 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141404
[email protected]49639fa2011-12-20 23:22:411405 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141406
tfarina42834112016-09-22 13:38:201407 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141409
1410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011411 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141412
bnc691fda62016-08-12 00:43:161413 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521414 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141415
wezca1070932016-05-26 20:30:521416 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141417 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1418
1419 std::string response_data;
bnc691fda62016-08-12 00:43:161420 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011421 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141422 EXPECT_EQ("hello world", response_data);
1423}
1424
bncd16676a2016-07-20 16:23:011425TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081426 HttpRequestInfo request;
1427 request.method = "POST";
1428 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081429
danakj1fd259a02016-04-16 03:17:091430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081432
1433 MockRead data_reads[] = {
1434 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1435 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381436 };
zmo9528c9f42015-08-04 22:12:081437 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381439
zmo9528c9f42015-08-04 22:12:081440 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381441
tfarina42834112016-09-22 13:38:201442 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381444
zmo9528c9f42015-08-04 22:12:081445 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011446 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381447
zmo9528c9f42015-08-04 22:12:081448 std::string response_data;
bnc691fda62016-08-12 00:43:161449 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011450 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081451 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381452}
1453
bncd16676a2016-07-20 16:23:011454TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381455 HttpRequestInfo request;
1456 request.method = "POST";
1457 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381458
danakj1fd259a02016-04-16 03:17:091459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271461
[email protected]ee9410e72010-01-07 01:42:381462 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061463 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381464 };
[email protected]31a2bfe2010-02-09 08:03:391465 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071466 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381467
[email protected]49639fa2011-12-20 23:22:411468 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381469
tfarina42834112016-09-22 13:38:201470 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381472
1473 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011474 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381475}
1476
[email protected]23e482282013-06-14 16:08:021477void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511478 const MockWrite* write_failure,
1479 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421480 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521481 request.method = "GET";
1482 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521483
vishal.b62985ca92015-04-17 08:45:511484 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071485 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091486 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271487
[email protected]202965992011-12-07 23:04:511488 // Written data for successfully sending both requests.
1489 MockWrite data1_writes[] = {
1490 MockWrite("GET / HTTP/1.1\r\n"
1491 "Host: www.foo.com\r\n"
1492 "Connection: keep-alive\r\n\r\n"),
1493 MockWrite("GET / HTTP/1.1\r\n"
1494 "Host: www.foo.com\r\n"
1495 "Connection: keep-alive\r\n\r\n")
1496 };
1497
1498 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521499 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351500 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1501 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061502 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521503 };
[email protected]202965992011-12-07 23:04:511504
1505 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491506 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511507 data1_writes[1] = *write_failure;
1508 } else {
1509 ASSERT_TRUE(read_failure);
1510 data1_reads[2] = *read_failure;
1511 }
1512
1513 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1514 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071515 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521516
1517 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351518 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1519 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061520 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521521 };
[email protected]31a2bfe2010-02-09 08:03:391522 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071523 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521524
thestig9d3bb0c2015-01-24 00:49:511525 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521526 "hello", "world"
1527 };
1528
mikecironef22f9812016-10-04 03:40:191529 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521530 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411531 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521532
bnc691fda62016-08-12 00:43:161533 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521534
tfarina42834112016-09-22 13:38:201535 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011536 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521537
1538 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011539 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521540
[email protected]58e32bb2013-01-21 18:23:251541 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161542 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251543 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1544 if (i == 0) {
1545 first_socket_log_id = load_timing_info.socket_log_id;
1546 } else {
1547 // The second request should be using a new socket.
1548 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1549 }
1550
bnc691fda62016-08-12 00:43:161551 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521552 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521553
wezca1070932016-05-26 20:30:521554 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471555 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251556 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521557
1558 std::string response_data;
bnc691fda62016-08-12 00:43:161559 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011560 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251561 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521562 }
1563}
[email protected]3d2a59b2008-09-26 19:44:251564
[email protected]a34f61ee2014-03-18 20:59:491565void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1566 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101567 const MockRead* read_failure,
1568 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491569 HttpRequestInfo request;
1570 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101571 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491572
vishal.b62985ca92015-04-17 08:45:511573 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491574 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491576
[email protected]09356c652014-03-25 15:36:101577 SSLSocketDataProvider ssl1(ASYNC, OK);
1578 SSLSocketDataProvider ssl2(ASYNC, OK);
1579 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361580 ssl1.next_proto = kProtoHTTP2;
1581 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101582 }
1583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1584 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491585
[email protected]09356c652014-03-25 15:36:101586 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411587 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491588 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411589 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151590 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411591 SpdySerializedFrame spdy_data(
1592 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491593
[email protected]09356c652014-03-25 15:36:101594 // HTTP/1.1 versions of the request and response.
1595 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1596 "Host: www.foo.com\r\n"
1597 "Connection: keep-alive\r\n\r\n";
1598 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1599 const char kHttpData[] = "hello";
1600
1601 std::vector<MockRead> data1_reads;
1602 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491603 if (write_failure) {
1604 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101605 data1_writes.push_back(*write_failure);
1606 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491607 } else {
1608 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101609 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411610 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101611 } else {
1612 data1_writes.push_back(MockWrite(kHttpRequest));
1613 }
1614 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491615 }
1616
[email protected]09356c652014-03-25 15:36:101617 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1618 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491619 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1620
[email protected]09356c652014-03-25 15:36:101621 std::vector<MockRead> data2_reads;
1622 std::vector<MockWrite> data2_writes;
1623
1624 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411625 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101626
bncdf80d44fd2016-07-15 20:27:411627 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1628 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101629 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1630 } else {
1631 data2_writes.push_back(
1632 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1633
1634 data2_reads.push_back(
1635 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1636 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1637 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1638 }
rch8e6c6c42015-05-01 14:05:131639 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1640 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491641 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1642
1643 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591644 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491645 // Wait for the preconnect to complete.
1646 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1647 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101648 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491649
1650 // Make the request.
1651 TestCompletionCallback callback;
1652
bnc691fda62016-08-12 00:43:161653 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491654
tfarina42834112016-09-22 13:38:201655 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491657
1658 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011659 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491660
1661 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161662 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101663 TestLoadTimingNotReused(
1664 load_timing_info,
1665 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491666
bnc691fda62016-08-12 00:43:161667 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521668 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491669
wezca1070932016-05-26 20:30:521670 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021671 if (response->was_fetched_via_spdy) {
1672 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1673 } else {
1674 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1675 }
[email protected]a34f61ee2014-03-18 20:59:491676
1677 std::string response_data;
bnc691fda62016-08-12 00:43:161678 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011679 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101680 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491681}
1682
bncd16676a2016-07-20 16:23:011683TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061684 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511685 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1686}
1687
bncd16676a2016-07-20 16:23:011688TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061689 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511690 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251691}
1692
bncd16676a2016-07-20 16:23:011693TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061694 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511695 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251696}
1697
[email protected]d58ceea82014-06-04 10:55:541698// Make sure that on a 408 response (Request Timeout), the request is retried,
1699// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011700TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541701 MockRead read_failure(SYNCHRONOUS,
1702 "HTTP/1.1 408 Request Timeout\r\n"
1703 "Connection: Keep-Alive\r\n"
1704 "Content-Length: 6\r\n\r\n"
1705 "Pickle");
1706 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1707}
1708
bncd16676a2016-07-20 16:23:011709TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491710 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101711 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491712}
1713
bncd16676a2016-07-20 16:23:011714TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491715 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101716 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491717}
1718
bncd16676a2016-07-20 16:23:011719TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491720 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101721 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1722}
1723
bncd16676a2016-07-20 16:23:011724TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101725 MockRead read_failure(ASYNC, OK); // EOF
1726 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1727}
1728
[email protected]d58ceea82014-06-04 10:55:541729// Make sure that on a 408 response (Request Timeout), the request is retried,
1730// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011731TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541732 MockRead read_failure(SYNCHRONOUS,
1733 "HTTP/1.1 408 Request Timeout\r\n"
1734 "Connection: Keep-Alive\r\n"
1735 "Content-Length: 6\r\n\r\n"
1736 "Pickle");
1737 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1738 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1739}
1740
bncd16676a2016-07-20 16:23:011741TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101742 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1743 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1744}
1745
bncd16676a2016-07-20 16:23:011746TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101747 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1748 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1749}
1750
bncd16676a2016-07-20 16:23:011751TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101752 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1753 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1754}
1755
bncd16676a2016-07-20 16:23:011756TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101757 MockRead read_failure(ASYNC, OK); // EOF
1758 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491759}
1760
bncd16676a2016-07-20 16:23:011761TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421762 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251763 request.method = "GET";
bncce36dca22015-04-21 22:11:231764 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251765
danakj1fd259a02016-04-16 03:17:091766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271768
[email protected]3d2a59b2008-09-26 19:44:251769 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061770 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351771 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1772 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061773 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251774 };
[email protected]31a2bfe2010-02-09 08:03:391775 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071776 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251777
[email protected]49639fa2011-12-20 23:22:411778 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251779
tfarina42834112016-09-22 13:38:201780 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011781 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251782
1783 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011784 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591785
1786 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161787 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591788 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251789}
1790
1791// What do various browsers do when the server closes a non-keepalive
1792// connection without sending any response header or body?
1793//
1794// IE7: error page
1795// Safari 3.1.2 (Windows): error page
1796// Firefox 3.0.1: blank page
1797// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421798// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1799// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011800TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251801 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061802 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351803 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1804 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061805 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251806 };
[email protected]31a2bfe2010-02-09 08:03:391807 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1808 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011809 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251810}
[email protected]1826a402014-01-08 15:40:481811
[email protected]7a5378b2012-11-04 03:25:171812// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1813// tests. There was a bug causing HttpNetworkTransaction to hang in the
1814// destructor in such situations.
1815// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011816TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171817 HttpRequestInfo request;
1818 request.method = "GET";
bncce36dca22015-04-21 22:11:231819 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171820
danakj1fd259a02016-04-16 03:17:091821 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581822 auto trans =
1823 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171824
1825 MockRead data_reads[] = {
1826 MockRead("HTTP/1.0 200 OK\r\n"),
1827 MockRead("Connection: keep-alive\r\n"),
1828 MockRead("Content-Length: 100\r\n\r\n"),
1829 MockRead("hello"),
1830 MockRead(SYNCHRONOUS, 0),
1831 };
1832 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071833 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171834
1835 TestCompletionCallback callback;
1836
tfarina42834112016-09-22 13:38:201837 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171839
1840 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011841 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171842
1843 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501844 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171845 if (rv == ERR_IO_PENDING)
1846 rv = callback.WaitForResult();
1847 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501848 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011849 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171850
1851 trans.reset();
fdoray92e35a72016-06-10 15:54:551852 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171853 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1854}
1855
bncd16676a2016-07-20 16:23:011856TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171857 HttpRequestInfo request;
1858 request.method = "GET";
bncce36dca22015-04-21 22:11:231859 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171860
danakj1fd259a02016-04-16 03:17:091861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581862 auto trans =
1863 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171864
1865 MockRead data_reads[] = {
1866 MockRead("HTTP/1.0 200 OK\r\n"),
1867 MockRead("Connection: keep-alive\r\n"),
1868 MockRead("Content-Length: 100\r\n\r\n"),
1869 MockRead(SYNCHRONOUS, 0),
1870 };
1871 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071872 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171873
1874 TestCompletionCallback callback;
1875
tfarina42834112016-09-22 13:38:201876 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171878
1879 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011880 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171881
1882 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501883 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171884 if (rv == ERR_IO_PENDING)
1885 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011886 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171887
1888 trans.reset();
fdoray92e35a72016-06-10 15:54:551889 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171890 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1891}
1892
[email protected]0b0bf032010-09-21 18:08:501893// Test that we correctly reuse a keep-alive connection after not explicitly
1894// reading the body.
bncd16676a2016-07-20 16:23:011895TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131896 HttpRequestInfo request;
1897 request.method = "GET";
1898 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131899
vishal.b62985ca92015-04-17 08:45:511900 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071901 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091902 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271903
mmenkecc2298e2015-12-07 18:20:181904 const char* request_data =
1905 "GET / HTTP/1.1\r\n"
1906 "Host: www.foo.com\r\n"
1907 "Connection: keep-alive\r\n\r\n";
1908 MockWrite data_writes[] = {
1909 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1910 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1911 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1912 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1913 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1914 };
1915
[email protected]0b0bf032010-09-21 18:08:501916 // Note that because all these reads happen in the same
1917 // StaticSocketDataProvider, it shows that the same socket is being reused for
1918 // all transactions.
mmenkecc2298e2015-12-07 18:20:181919 MockRead data_reads[] = {
1920 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1921 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1922 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1923 MockRead(ASYNC, 7,
1924 "HTTP/1.1 302 Found\r\n"
1925 "Content-Length: 0\r\n\r\n"),
1926 MockRead(ASYNC, 9,
1927 "HTTP/1.1 302 Found\r\n"
1928 "Content-Length: 5\r\n\r\n"
1929 "hello"),
1930 MockRead(ASYNC, 11,
1931 "HTTP/1.1 301 Moved Permanently\r\n"
1932 "Content-Length: 0\r\n\r\n"),
1933 MockRead(ASYNC, 13,
1934 "HTTP/1.1 301 Moved Permanently\r\n"
1935 "Content-Length: 5\r\n\r\n"
1936 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131937
mmenkecc2298e2015-12-07 18:20:181938 // In the next two rounds, IsConnectedAndIdle returns false, due to
1939 // the set_busy_before_sync_reads(true) call, while the
1940 // HttpNetworkTransaction is being shut down, but the socket is still
1941 // reuseable. See http://crbug.com/544255.
1942 MockRead(ASYNC, 15,
1943 "HTTP/1.1 200 Hunky-Dory\r\n"
1944 "Content-Length: 5\r\n\r\n"),
1945 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131946
mmenkecc2298e2015-12-07 18:20:181947 MockRead(ASYNC, 18,
1948 "HTTP/1.1 200 Hunky-Dory\r\n"
1949 "Content-Length: 5\r\n\r\n"
1950 "he"),
1951 MockRead(SYNCHRONOUS, 19, "llo"),
1952
1953 // The body of the final request is actually read.
1954 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1955 MockRead(ASYNC, 22, "hello"),
1956 };
1957 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1958 arraysize(data_writes));
1959 data.set_busy_before_sync_reads(true);
1960 session_deps_.socket_factory->AddSocketDataProvider(&data);
1961
1962 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501963 std::string response_lines[kNumUnreadBodies];
1964
mikecironef22f9812016-10-04 03:40:191965 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181966 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411967 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131968
bnc87dcefc2017-05-25 12:47:581969 auto trans = base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
1970 session.get());
[email protected]fc31d6a42010-06-24 18:05:131971
tfarina42834112016-09-22 13:38:201972 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011973 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131974
[email protected]58e32bb2013-01-21 18:23:251975 LoadTimingInfo load_timing_info;
1976 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1977 if (i == 0) {
1978 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1979 first_socket_log_id = load_timing_info.socket_log_id;
1980 } else {
1981 TestLoadTimingReused(load_timing_info);
1982 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1983 }
1984
[email protected]fc31d6a42010-06-24 18:05:131985 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181986 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131987
mmenkecc2298e2015-12-07 18:20:181988 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501989 response_lines[i] = response->headers->GetStatusLine();
1990
mmenkecc2298e2015-12-07 18:20:181991 // Delete the transaction without reading the response bodies. Then spin
1992 // the message loop, so the response bodies are drained.
1993 trans.reset();
1994 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131995 }
[email protected]0b0bf032010-09-21 18:08:501996
1997 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181998 "HTTP/1.1 204 No Content",
1999 "HTTP/1.1 205 Reset Content",
2000 "HTTP/1.1 304 Not Modified",
2001 "HTTP/1.1 302 Found",
2002 "HTTP/1.1 302 Found",
2003 "HTTP/1.1 301 Moved Permanently",
2004 "HTTP/1.1 301 Moved Permanently",
2005 "HTTP/1.1 200 Hunky-Dory",
2006 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502007 };
2008
mostynb91e0da982015-01-20 19:17:272009 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2010 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502011
2012 for (int i = 0; i < kNumUnreadBodies; ++i)
2013 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2014
[email protected]49639fa2011-12-20 23:22:412015 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162016 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202017 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012018 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162019 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182020 ASSERT_TRUE(response);
2021 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502022 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2023 std::string response_data;
bnc691fda62016-08-12 00:43:162024 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012025 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502026 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132027}
2028
mmenke5f94fda2016-06-02 20:54:132029// Sockets that receive extra data after a response is complete should not be
2030// reused.
bncd16676a2016-07-20 16:23:012031TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2033 MockWrite data_writes1[] = {
2034 MockWrite("HEAD / HTTP/1.1\r\n"
2035 "Host: www.borked.com\r\n"
2036 "Connection: keep-alive\r\n\r\n"),
2037 };
2038
2039 MockRead data_reads1[] = {
2040 MockRead("HTTP/1.1 200 OK\r\n"
2041 "Connection: keep-alive\r\n"
2042 "Content-Length: 22\r\n\r\n"
2043 "This server is borked."),
2044 };
2045
2046 MockWrite data_writes2[] = {
2047 MockWrite("GET /foo HTTP/1.1\r\n"
2048 "Host: www.borked.com\r\n"
2049 "Connection: keep-alive\r\n\r\n"),
2050 };
2051
2052 MockRead data_reads2[] = {
2053 MockRead("HTTP/1.1 200 OK\r\n"
2054 "Content-Length: 3\r\n\r\n"
2055 "foo"),
2056 };
2057 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2058 data_writes1, arraysize(data_writes1));
2059 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2060 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2061 data_writes2, arraysize(data_writes2));
2062 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2063
2064 TestCompletionCallback callback;
2065 HttpRequestInfo request1;
2066 request1.method = "HEAD";
2067 request1.url = GURL("http://www.borked.com/");
2068
bnc87dcefc2017-05-25 12:47:582069 auto trans1 =
2070 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202071 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012072 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132073
2074 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2075 ASSERT_TRUE(response1);
2076 ASSERT_TRUE(response1->headers);
2077 EXPECT_EQ(200, response1->headers->response_code());
2078 EXPECT_TRUE(response1->headers->IsKeepAlive());
2079
2080 std::string response_data1;
robpercival214763f2016-07-01 23:27:012081 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132082 EXPECT_EQ("", response_data1);
2083 // Deleting the transaction attempts to release the socket back into the
2084 // socket pool.
2085 trans1.reset();
2086
2087 HttpRequestInfo request2;
2088 request2.method = "GET";
2089 request2.url = GURL("http://www.borked.com/foo");
2090
bnc87dcefc2017-05-25 12:47:582091 auto trans2 =
2092 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202093 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012094 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132095
2096 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2097 ASSERT_TRUE(response2);
2098 ASSERT_TRUE(response2->headers);
2099 EXPECT_EQ(200, response2->headers->response_code());
2100
2101 std::string response_data2;
robpercival214763f2016-07-01 23:27:012102 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132103 EXPECT_EQ("foo", response_data2);
2104}
2105
bncd16676a2016-07-20 16:23:012106TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132107 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2108 MockWrite data_writes1[] = {
2109 MockWrite("GET / HTTP/1.1\r\n"
2110 "Host: www.borked.com\r\n"
2111 "Connection: keep-alive\r\n\r\n"),
2112 };
2113
2114 MockRead data_reads1[] = {
2115 MockRead("HTTP/1.1 200 OK\r\n"
2116 "Connection: keep-alive\r\n"
2117 "Content-Length: 22\r\n\r\n"
2118 "This server is borked."
2119 "Bonus data!"),
2120 };
2121
2122 MockWrite data_writes2[] = {
2123 MockWrite("GET /foo HTTP/1.1\r\n"
2124 "Host: www.borked.com\r\n"
2125 "Connection: keep-alive\r\n\r\n"),
2126 };
2127
2128 MockRead data_reads2[] = {
2129 MockRead("HTTP/1.1 200 OK\r\n"
2130 "Content-Length: 3\r\n\r\n"
2131 "foo"),
2132 };
2133 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2134 data_writes1, arraysize(data_writes1));
2135 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2136 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2137 data_writes2, arraysize(data_writes2));
2138 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2139
2140 TestCompletionCallback callback;
2141 HttpRequestInfo request1;
2142 request1.method = "GET";
2143 request1.url = GURL("http://www.borked.com/");
2144
bnc87dcefc2017-05-25 12:47:582145 auto trans1 =
2146 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202147 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012148 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132149
2150 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2151 ASSERT_TRUE(response1);
2152 ASSERT_TRUE(response1->headers);
2153 EXPECT_EQ(200, response1->headers->response_code());
2154 EXPECT_TRUE(response1->headers->IsKeepAlive());
2155
2156 std::string response_data1;
robpercival214763f2016-07-01 23:27:012157 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132158 EXPECT_EQ("This server is borked.", response_data1);
2159 // Deleting the transaction attempts to release the socket back into the
2160 // socket pool.
2161 trans1.reset();
2162
2163 HttpRequestInfo request2;
2164 request2.method = "GET";
2165 request2.url = GURL("http://www.borked.com/foo");
2166
bnc87dcefc2017-05-25 12:47:582167 auto trans2 =
2168 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202169 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012170 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132171
2172 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2173 ASSERT_TRUE(response2);
2174 ASSERT_TRUE(response2->headers);
2175 EXPECT_EQ(200, response2->headers->response_code());
2176
2177 std::string response_data2;
robpercival214763f2016-07-01 23:27:012178 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132179 EXPECT_EQ("foo", response_data2);
2180}
2181
bncd16676a2016-07-20 16:23:012182TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132183 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2184 MockWrite data_writes1[] = {
2185 MockWrite("GET / HTTP/1.1\r\n"
2186 "Host: www.borked.com\r\n"
2187 "Connection: keep-alive\r\n\r\n"),
2188 };
2189
2190 MockRead data_reads1[] = {
2191 MockRead("HTTP/1.1 200 OK\r\n"
2192 "Connection: keep-alive\r\n"
2193 "Transfer-Encoding: chunked\r\n\r\n"),
2194 MockRead("16\r\nThis server is borked.\r\n"),
2195 MockRead("0\r\n\r\nBonus data!"),
2196 };
2197
2198 MockWrite data_writes2[] = {
2199 MockWrite("GET /foo HTTP/1.1\r\n"
2200 "Host: www.borked.com\r\n"
2201 "Connection: keep-alive\r\n\r\n"),
2202 };
2203
2204 MockRead data_reads2[] = {
2205 MockRead("HTTP/1.1 200 OK\r\n"
2206 "Content-Length: 3\r\n\r\n"
2207 "foo"),
2208 };
2209 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2210 data_writes1, arraysize(data_writes1));
2211 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2212 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2213 data_writes2, arraysize(data_writes2));
2214 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2215
2216 TestCompletionCallback callback;
2217 HttpRequestInfo request1;
2218 request1.method = "GET";
2219 request1.url = GURL("http://www.borked.com/");
2220
bnc87dcefc2017-05-25 12:47:582221 auto trans1 =
2222 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202223 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012224 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132225
2226 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2227 ASSERT_TRUE(response1);
2228 ASSERT_TRUE(response1->headers);
2229 EXPECT_EQ(200, response1->headers->response_code());
2230 EXPECT_TRUE(response1->headers->IsKeepAlive());
2231
2232 std::string response_data1;
robpercival214763f2016-07-01 23:27:012233 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132234 EXPECT_EQ("This server is borked.", response_data1);
2235 // Deleting the transaction attempts to release the socket back into the
2236 // socket pool.
2237 trans1.reset();
2238
2239 HttpRequestInfo request2;
2240 request2.method = "GET";
2241 request2.url = GURL("http://www.borked.com/foo");
2242
bnc87dcefc2017-05-25 12:47:582243 auto trans2 =
2244 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202245 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012246 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132247
2248 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2249 ASSERT_TRUE(response2);
2250 ASSERT_TRUE(response2->headers);
2251 EXPECT_EQ(200, response2->headers->response_code());
2252
2253 std::string response_data2;
robpercival214763f2016-07-01 23:27:012254 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132255 EXPECT_EQ("foo", response_data2);
2256}
2257
2258// This is a little different from the others - it tests the case that the
2259// HttpStreamParser doesn't know if there's extra data on a socket or not when
2260// the HttpNetworkTransaction is torn down, because the response body hasn't
2261// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012262TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2264 MockWrite data_writes1[] = {
2265 MockWrite("GET / HTTP/1.1\r\n"
2266 "Host: www.borked.com\r\n"
2267 "Connection: keep-alive\r\n\r\n"),
2268 };
2269
2270 MockRead data_reads1[] = {
2271 MockRead("HTTP/1.1 200 OK\r\n"
2272 "Connection: keep-alive\r\n"
2273 "Transfer-Encoding: chunked\r\n\r\n"),
2274 MockRead("16\r\nThis server is borked.\r\n"),
2275 MockRead("0\r\n\r\nBonus data!"),
2276 };
2277 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2278 data_writes1, arraysize(data_writes1));
2279 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2280
2281 TestCompletionCallback callback;
2282 HttpRequestInfo request1;
2283 request1.method = "GET";
2284 request1.url = GURL("http://www.borked.com/");
2285
bnc87dcefc2017-05-25 12:47:582286 auto trans =
2287 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2288 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012289 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132290
bnc87dcefc2017-05-25 12:47:582291 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132292 ASSERT_TRUE(response1);
2293 ASSERT_TRUE(response1->headers);
2294 EXPECT_EQ(200, response1->headers->response_code());
2295 EXPECT_TRUE(response1->headers->IsKeepAlive());
2296
2297 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2298 // response body.
bnc87dcefc2017-05-25 12:47:582299 trans.reset();
mmenke5f94fda2016-06-02 20:54:132300
2301 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2302 // socket can't be reused, rather than returning it to the socket pool.
2303 base::RunLoop().RunUntilIdle();
2304
2305 // There should be no idle sockets in the pool.
2306 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2307}
2308
[email protected]038e9a32008-10-08 22:40:162309// Test the request-challenge-retry sequence for basic auth.
2310// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012311TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422312 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162313 request.method = "GET";
bncce36dca22015-04-21 22:11:232314 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162315
vishal.b62985ca92015-04-17 08:45:512316 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072317 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092318 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162319 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272320
[email protected]f9ee6b52008-11-08 06:46:232321 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232322 MockWrite(
2323 "GET / HTTP/1.1\r\n"
2324 "Host: www.example.org\r\n"
2325 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232326 };
2327
[email protected]038e9a32008-10-08 22:40:162328 MockRead data_reads1[] = {
2329 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2330 // Give a couple authenticate options (only the middle one is actually
2331 // supported).
[email protected]22927ad2009-09-21 19:56:192332 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162333 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2334 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2335 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2336 // Large content-length -- won't matter, as connection will be reset.
2337 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062338 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162339 };
2340
2341 // After calling trans->RestartWithAuth(), this is the request we should
2342 // be issuing -- the final header line contains the credentials.
2343 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232344 MockWrite(
2345 "GET / HTTP/1.1\r\n"
2346 "Host: www.example.org\r\n"
2347 "Connection: keep-alive\r\n"
2348 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162349 };
2350
2351 // Lastly, the server responds with the actual content.
2352 MockRead data_reads2[] = {
2353 MockRead("HTTP/1.0 200 OK\r\n"),
2354 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2355 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062356 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162357 };
2358
[email protected]31a2bfe2010-02-09 08:03:392359 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2360 data_writes1, arraysize(data_writes1));
2361 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2362 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072363 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2364 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162365
[email protected]49639fa2011-12-20 23:22:412366 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162367
tfarina42834112016-09-22 13:38:202368 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162370
2371 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012372 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162373
[email protected]58e32bb2013-01-21 18:23:252374 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162375 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252376 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2377
sclittlefb249892015-09-10 21:33:222378 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162379 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222380 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162381 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192382
bnc691fda62016-08-12 00:43:162383 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522384 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042385 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162386
[email protected]49639fa2011-12-20 23:22:412387 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162388
bnc691fda62016-08-12 00:43:162389 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162391
2392 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012393 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162394
[email protected]58e32bb2013-01-21 18:23:252395 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162396 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252397 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2398 // The load timing after restart should have a new socket ID, and times after
2399 // those of the first load timing.
2400 EXPECT_LE(load_timing_info1.receive_headers_end,
2401 load_timing_info2.connect_timing.connect_start);
2402 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2403
sclittlefb249892015-09-10 21:33:222404 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162405 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222406 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162407 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192408
bnc691fda62016-08-12 00:43:162409 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522410 ASSERT_TRUE(response);
2411 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162412 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162413}
2414
ttuttled9dbc652015-09-29 20:00:592415// Test the request-challenge-retry sequence for basic auth.
2416// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012417TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592418 HttpRequestInfo request;
2419 request.method = "GET";
2420 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592421
2422 TestNetLog log;
2423 MockHostResolver* resolver = new MockHostResolver();
2424 session_deps_.net_log = &log;
2425 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092426 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162427 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592428
2429 resolver->rules()->ClearRules();
2430 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2431
2432 MockWrite data_writes1[] = {
2433 MockWrite("GET / HTTP/1.1\r\n"
2434 "Host: www.example.org\r\n"
2435 "Connection: keep-alive\r\n\r\n"),
2436 };
2437
2438 MockRead data_reads1[] = {
2439 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2440 // Give a couple authenticate options (only the middle one is actually
2441 // supported).
2442 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2443 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2444 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2445 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2446 // Large content-length -- won't matter, as connection will be reset.
2447 MockRead("Content-Length: 10000\r\n\r\n"),
2448 MockRead(SYNCHRONOUS, ERR_FAILED),
2449 };
2450
2451 // After calling trans->RestartWithAuth(), this is the request we should
2452 // be issuing -- the final header line contains the credentials.
2453 MockWrite data_writes2[] = {
2454 MockWrite("GET / HTTP/1.1\r\n"
2455 "Host: www.example.org\r\n"
2456 "Connection: keep-alive\r\n"
2457 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2458 };
2459
2460 // Lastly, the server responds with the actual content.
2461 MockRead data_reads2[] = {
2462 MockRead("HTTP/1.0 200 OK\r\n"),
2463 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2464 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2465 };
2466
2467 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2468 data_writes1, arraysize(data_writes1));
2469 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2470 data_writes2, arraysize(data_writes2));
2471 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2472 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2473
2474 TestCompletionCallback callback1;
2475
bnc691fda62016-08-12 00:43:162476 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202477 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592478
2479 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162480 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592481 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2482
2483 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162484 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592485 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162486 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592487
bnc691fda62016-08-12 00:43:162488 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592489 ASSERT_TRUE(response);
2490 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2491
2492 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162493 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592494 ASSERT_FALSE(endpoint.address().empty());
2495 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2496
2497 resolver->rules()->ClearRules();
2498 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2499
2500 TestCompletionCallback callback2;
2501
bnc691fda62016-08-12 00:43:162502 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592503 AuthCredentials(kFoo, kBar), callback2.callback())));
2504
2505 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162506 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592507 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2508 // The load timing after restart should have a new socket ID, and times after
2509 // those of the first load timing.
2510 EXPECT_LE(load_timing_info1.receive_headers_end,
2511 load_timing_info2.connect_timing.connect_start);
2512 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2513
2514 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162515 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592516 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162517 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592518
bnc691fda62016-08-12 00:43:162519 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592520 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522521 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592522 EXPECT_EQ(100, response->headers->GetContentLength());
2523
bnc691fda62016-08-12 00:43:162524 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592525 ASSERT_FALSE(endpoint.address().empty());
2526 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2527}
2528
bncd16676a2016-07-20 16:23:012529TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462530 HttpRequestInfo request;
2531 request.method = "GET";
bncce36dca22015-04-21 22:11:232532 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292533 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462534
danakj1fd259a02016-04-16 03:17:092535 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162536 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272537
[email protected]861fcd52009-08-26 02:33:462538 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232539 MockWrite(
2540 "GET / HTTP/1.1\r\n"
2541 "Host: www.example.org\r\n"
2542 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462543 };
2544
2545 MockRead data_reads[] = {
2546 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2547 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2548 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2549 // Large content-length -- won't matter, as connection will be reset.
2550 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062551 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462552 };
2553
[email protected]31a2bfe2010-02-09 08:03:392554 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2555 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072556 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412557 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462558
tfarina42834112016-09-22 13:38:202559 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012560 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462561
2562 rv = callback.WaitForResult();
2563 EXPECT_EQ(0, rv);
2564
sclittlefb249892015-09-10 21:33:222565 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162566 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222567 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162568 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192569
bnc691fda62016-08-12 00:43:162570 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522571 ASSERT_TRUE(response);
2572 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462573}
2574
[email protected]2d2697f92009-02-18 21:00:322575// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2576// connection.
bncd16676a2016-07-20 16:23:012577TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182578 // On the second pass, the body read of the auth challenge is synchronous, so
2579 // IsConnectedAndIdle returns false. The socket should still be drained and
2580 // reused. See http://crbug.com/544255.
2581 for (int i = 0; i < 2; ++i) {
2582 HttpRequestInfo request;
2583 request.method = "GET";
2584 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322585
mmenkecc2298e2015-12-07 18:20:182586 TestNetLog log;
2587 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272589
mmenkecc2298e2015-12-07 18:20:182590 MockWrite data_writes[] = {
2591 MockWrite(ASYNC, 0,
2592 "GET / HTTP/1.1\r\n"
2593 "Host: www.example.org\r\n"
2594 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322595
bnc691fda62016-08-12 00:43:162596 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182597 // be issuing -- the final header line contains the credentials.
2598 MockWrite(ASYNC, 6,
2599 "GET / HTTP/1.1\r\n"
2600 "Host: www.example.org\r\n"
2601 "Connection: keep-alive\r\n"
2602 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2603 };
[email protected]2d2697f92009-02-18 21:00:322604
mmenkecc2298e2015-12-07 18:20:182605 MockRead data_reads[] = {
2606 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2607 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2608 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2609 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2610 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322611
mmenkecc2298e2015-12-07 18:20:182612 // Lastly, the server responds with the actual content.
2613 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2614 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2615 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2616 MockRead(ASYNC, 10, "Hello"),
2617 };
[email protected]2d2697f92009-02-18 21:00:322618
mmenkecc2298e2015-12-07 18:20:182619 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2620 arraysize(data_writes));
2621 data.set_busy_before_sync_reads(true);
2622 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462623
mmenkecc2298e2015-12-07 18:20:182624 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322625
bnc691fda62016-08-12 00:43:162626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202627 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012628 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322629
mmenkecc2298e2015-12-07 18:20:182630 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162631 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182632 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322633
bnc691fda62016-08-12 00:43:162634 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182635 ASSERT_TRUE(response);
2636 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322637
mmenkecc2298e2015-12-07 18:20:182638 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252639
bnc691fda62016-08-12 00:43:162640 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2641 callback2.callback());
robpercival214763f2016-07-01 23:27:012642 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322643
mmenkecc2298e2015-12-07 18:20:182644 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162645 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182646 TestLoadTimingReused(load_timing_info2);
2647 // The load timing after restart should have the same socket ID, and times
2648 // those of the first load timing.
2649 EXPECT_LE(load_timing_info1.receive_headers_end,
2650 load_timing_info2.send_start);
2651 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322652
bnc691fda62016-08-12 00:43:162653 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182654 ASSERT_TRUE(response);
2655 EXPECT_FALSE(response->auth_challenge);
2656 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322657
mmenkecc2298e2015-12-07 18:20:182658 std::string response_data;
bnc691fda62016-08-12 00:43:162659 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322660
mmenkecc2298e2015-12-07 18:20:182661 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162662 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182663 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162664 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182665 }
[email protected]2d2697f92009-02-18 21:00:322666}
2667
2668// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2669// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012670TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422671 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322672 request.method = "GET";
bncce36dca22015-04-21 22:11:232673 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322674
danakj1fd259a02016-04-16 03:17:092675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272676
[email protected]2d2697f92009-02-18 21:00:322677 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162678 MockWrite("GET / HTTP/1.1\r\n"
2679 "Host: www.example.org\r\n"
2680 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322681
bnc691fda62016-08-12 00:43:162682 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232683 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162684 MockWrite("GET / HTTP/1.1\r\n"
2685 "Host: www.example.org\r\n"
2686 "Connection: keep-alive\r\n"
2687 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322688 };
2689
[email protected]2d2697f92009-02-18 21:00:322690 MockRead data_reads1[] = {
2691 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2692 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312693 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322694
2695 // Lastly, the server responds with the actual content.
2696 MockRead("HTTP/1.1 200 OK\r\n"),
2697 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502698 MockRead("Content-Length: 5\r\n\r\n"),
2699 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322700 };
2701
[email protected]2d0a4f92011-05-05 16:38:462702 // An incorrect reconnect would cause this to be read.
2703 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062704 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462705 };
2706
[email protected]31a2bfe2010-02-09 08:03:392707 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2708 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462709 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2710 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072711 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2712 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322713
[email protected]49639fa2011-12-20 23:22:412714 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322715
bnc691fda62016-08-12 00:43:162716 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202717 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322719
2720 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012721 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322722
bnc691fda62016-08-12 00:43:162723 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522724 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042725 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322726
[email protected]49639fa2011-12-20 23:22:412727 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322728
bnc691fda62016-08-12 00:43:162729 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322731
2732 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012733 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322734
bnc691fda62016-08-12 00:43:162735 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522736 ASSERT_TRUE(response);
2737 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502738 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322739}
2740
2741// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2742// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012743TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422744 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322745 request.method = "GET";
bncce36dca22015-04-21 22:11:232746 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322747
danakj1fd259a02016-04-16 03:17:092748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272749
[email protected]2d2697f92009-02-18 21:00:322750 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162751 MockWrite("GET / HTTP/1.1\r\n"
2752 "Host: www.example.org\r\n"
2753 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322754
bnc691fda62016-08-12 00:43:162755 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232756 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162757 MockWrite("GET / HTTP/1.1\r\n"
2758 "Host: www.example.org\r\n"
2759 "Connection: keep-alive\r\n"
2760 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322761 };
2762
2763 // Respond with 5 kb of response body.
2764 std::string large_body_string("Unauthorized");
2765 large_body_string.append(5 * 1024, ' ');
2766 large_body_string.append("\r\n");
2767
2768 MockRead data_reads1[] = {
2769 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2770 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2771 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2772 // 5134 = 12 + 5 * 1024 + 2
2773 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062774 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322775
2776 // Lastly, the server responds with the actual content.
2777 MockRead("HTTP/1.1 200 OK\r\n"),
2778 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502779 MockRead("Content-Length: 5\r\n\r\n"),
2780 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322781 };
2782
[email protected]2d0a4f92011-05-05 16:38:462783 // An incorrect reconnect would cause this to be read.
2784 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062785 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462786 };
2787
[email protected]31a2bfe2010-02-09 08:03:392788 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2789 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462790 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2791 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072792 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2793 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322794
[email protected]49639fa2011-12-20 23:22:412795 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322796
bnc691fda62016-08-12 00:43:162797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202798 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322800
2801 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012802 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322803
bnc691fda62016-08-12 00:43:162804 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522805 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042806 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322807
[email protected]49639fa2011-12-20 23:22:412808 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322809
bnc691fda62016-08-12 00:43:162810 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322812
2813 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012814 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322815
bnc691fda62016-08-12 00:43:162816 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522817 ASSERT_TRUE(response);
2818 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502819 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322820}
2821
2822// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312823// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012824TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312825 HttpRequestInfo request;
2826 request.method = "GET";
bncce36dca22015-04-21 22:11:232827 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312828
danakj1fd259a02016-04-16 03:17:092829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272830
[email protected]11203f012009-11-12 23:02:312831 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232832 MockWrite(
2833 "GET / HTTP/1.1\r\n"
2834 "Host: www.example.org\r\n"
2835 "Connection: keep-alive\r\n\r\n"),
2836 // This simulates the seemingly successful write to a closed connection
2837 // if the bug is not fixed.
2838 MockWrite(
2839 "GET / HTTP/1.1\r\n"
2840 "Host: www.example.org\r\n"
2841 "Connection: keep-alive\r\n"
2842 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312843 };
2844
2845 MockRead data_reads1[] = {
2846 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2847 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2848 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2849 MockRead("Content-Length: 14\r\n\r\n"),
2850 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062851 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312852 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062853 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312854 };
2855
bnc691fda62016-08-12 00:43:162856 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312857 // be issuing -- the final header line contains the credentials.
2858 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232859 MockWrite(
2860 "GET / HTTP/1.1\r\n"
2861 "Host: www.example.org\r\n"
2862 "Connection: keep-alive\r\n"
2863 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312864 };
2865
2866 // Lastly, the server responds with the actual content.
2867 MockRead data_reads2[] = {
2868 MockRead("HTTP/1.1 200 OK\r\n"),
2869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502870 MockRead("Content-Length: 5\r\n\r\n"),
2871 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312872 };
2873
[email protected]31a2bfe2010-02-09 08:03:392874 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2875 data_writes1, arraysize(data_writes1));
2876 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2877 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2879 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312880
[email protected]49639fa2011-12-20 23:22:412881 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312882
bnc691fda62016-08-12 00:43:162883 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202884 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312886
2887 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012888 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312889
bnc691fda62016-08-12 00:43:162890 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522891 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042892 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312893
[email protected]49639fa2011-12-20 23:22:412894 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312895
bnc691fda62016-08-12 00:43:162896 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312898
2899 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012900 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312901
bnc691fda62016-08-12 00:43:162902 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522903 ASSERT_TRUE(response);
2904 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502905 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312906}
2907
[email protected]394816e92010-08-03 07:38:592908// Test the request-challenge-retry sequence for basic auth, over a connection
2909// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012910TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012911 HttpRequestInfo request;
2912 request.method = "GET";
bncce36dca22015-04-21 22:11:232913 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012914 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292915 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012916
2917 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032918 session_deps_.proxy_service =
2919 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512920 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012921 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012923
2924 // Since we have proxy, should try to establish tunnel.
2925 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542926 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172927 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542928 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012929 };
2930
mmenkee71e15332015-10-07 16:39:542931 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012932 // connection.
2933 MockRead data_reads1[] = {
2934 // No credentials.
2935 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2936 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542937 };
ttuttle34f63b52015-03-05 04:33:012938
mmenkee71e15332015-10-07 16:39:542939 // Since the first connection couldn't be reused, need to establish another
2940 // once given credentials.
2941 MockWrite data_writes2[] = {
2942 // After calling trans->RestartWithAuth(), this is the request we should
2943 // be issuing -- the final header line contains the credentials.
2944 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172945 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542946 "Proxy-Connection: keep-alive\r\n"
2947 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2948
2949 MockWrite("GET / HTTP/1.1\r\n"
2950 "Host: www.example.org\r\n"
2951 "Connection: keep-alive\r\n\r\n"),
2952 };
2953
2954 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012955 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2956
2957 MockRead("HTTP/1.1 200 OK\r\n"),
2958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2959 MockRead("Content-Length: 5\r\n\r\n"),
2960 MockRead(SYNCHRONOUS, "hello"),
2961 };
2962
2963 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2964 data_writes1, arraysize(data_writes1));
2965 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542966 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2967 data_writes2, arraysize(data_writes2));
2968 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012969 SSLSocketDataProvider ssl(ASYNC, OK);
2970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2971
2972 TestCompletionCallback callback1;
2973
bnc87dcefc2017-05-25 12:47:582974 auto trans =
2975 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:012976
2977 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012979
2980 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012981 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462982 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012983 log.GetEntries(&entries);
2984 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002985 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2986 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012987 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002988 entries, pos,
2989 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2990 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012991
2992 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522993 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012994 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522995 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012996 EXPECT_EQ(407, response->headers->response_code());
2997 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2998 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2999
3000 LoadTimingInfo load_timing_info;
3001 // CONNECT requests and responses are handled at the connect job level, so
3002 // the transaction does not yet have a connection.
3003 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3004
3005 TestCompletionCallback callback2;
3006
3007 rv =
3008 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013010
3011 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013012 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013013
3014 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523015 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013016
3017 EXPECT_TRUE(response->headers->IsKeepAlive());
3018 EXPECT_EQ(200, response->headers->response_code());
3019 EXPECT_EQ(5, response->headers->GetContentLength());
3020 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3021
3022 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523023 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013024
3025 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3026 TestLoadTimingNotReusedWithPac(load_timing_info,
3027 CONNECT_TIMING_HAS_SSL_TIMES);
3028
3029 trans.reset();
3030 session->CloseAllConnections();
3031}
3032
3033// Test the request-challenge-retry sequence for basic auth, over a connection
3034// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013035TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593036 HttpRequestInfo request;
3037 request.method = "GET";
bncce36dca22015-04-21 22:11:233038 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593039 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293040 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593041
[email protected]cb9bf6ca2011-01-28 13:15:273042 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033043 session_deps_.proxy_service =
3044 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513045 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073046 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273048
[email protected]394816e92010-08-03 07:38:593049 // Since we have proxy, should try to establish tunnel.
3050 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543051 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173052 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543053 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113054 };
3055
mmenkee71e15332015-10-07 16:39:543056 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083057 // connection.
3058 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543059 // No credentials.
3060 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3061 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3062 MockRead("Proxy-Connection: close\r\n\r\n"),
3063 };
mmenkee0b5c882015-08-26 20:29:113064
mmenkee71e15332015-10-07 16:39:543065 MockWrite data_writes2[] = {
3066 // After calling trans->RestartWithAuth(), this is the request we should
3067 // be issuing -- the final header line contains the credentials.
3068 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173069 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543070 "Proxy-Connection: keep-alive\r\n"
3071 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083072
mmenkee71e15332015-10-07 16:39:543073 MockWrite("GET / HTTP/1.1\r\n"
3074 "Host: www.example.org\r\n"
3075 "Connection: keep-alive\r\n\r\n"),
3076 };
3077
3078 MockRead data_reads2[] = {
3079 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3080
3081 MockRead("HTTP/1.1 200 OK\r\n"),
3082 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3083 MockRead("Content-Length: 5\r\n\r\n"),
3084 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593085 };
3086
3087 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3088 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073089 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543090 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3091 data_writes2, arraysize(data_writes2));
3092 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063093 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073094 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593095
[email protected]49639fa2011-12-20 23:22:413096 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593097
bnc87dcefc2017-05-25 12:47:583098 auto trans =
3099 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503100
[email protected]49639fa2011-12-20 23:22:413101 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593103
3104 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013105 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463106 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403107 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593108 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003109 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3110 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593111 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403112 entries, pos,
mikecirone8b85c432016-09-08 19:11:003113 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3114 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593115
3116 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523117 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013118 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523119 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593120 EXPECT_EQ(407, response->headers->response_code());
3121 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043122 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593123
[email protected]029c83b62013-01-24 05:28:203124 LoadTimingInfo load_timing_info;
3125 // CONNECT requests and responses are handled at the connect job level, so
3126 // the transaction does not yet have a connection.
3127 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3128
[email protected]49639fa2011-12-20 23:22:413129 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593130
[email protected]49639fa2011-12-20 23:22:413131 rv = trans->RestartWithAuth(
3132 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013133 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593134
3135 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013136 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593137
3138 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523139 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593140
3141 EXPECT_TRUE(response->headers->IsKeepAlive());
3142 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503143 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593144 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3145
3146 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523147 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503148
[email protected]029c83b62013-01-24 05:28:203149 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3150 TestLoadTimingNotReusedWithPac(load_timing_info,
3151 CONNECT_TIMING_HAS_SSL_TIMES);
3152
[email protected]0b0bf032010-09-21 18:08:503153 trans.reset();
[email protected]102e27c2011-02-23 01:01:313154 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593155}
3156
[email protected]11203f012009-11-12 23:02:313157// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013158// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013159TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233160 // On the second pass, the body read of the auth challenge is synchronous, so
3161 // IsConnectedAndIdle returns false. The socket should still be drained and
3162 // reused. See http://crbug.com/544255.
3163 for (int i = 0; i < 2; ++i) {
3164 HttpRequestInfo request;
3165 request.method = "GET";
3166 request.url = GURL("https://www.example.org/");
3167 // Ensure that proxy authentication is attempted even
3168 // when the no authentication data flag is set.
3169 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013170
mmenked39192ee2015-12-09 00:57:233171 // Configure against proxy server "myproxy:70".
3172 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3173 BoundTestNetLog log;
3174 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093175 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013176
bnc691fda62016-08-12 00:43:163177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013178
mmenked39192ee2015-12-09 00:57:233179 // Since we have proxy, should try to establish tunnel.
3180 MockWrite data_writes1[] = {
3181 MockWrite(ASYNC, 0,
3182 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3183 "Host: www.example.org:443\r\n"
3184 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013185
bnc691fda62016-08-12 00:43:163186 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233187 // be issuing -- the final header line contains the credentials.
3188 MockWrite(ASYNC, 3,
3189 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3190 "Host: www.example.org:443\r\n"
3191 "Proxy-Connection: keep-alive\r\n"
3192 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3193 };
ttuttle34f63b52015-03-05 04:33:013194
mmenked39192ee2015-12-09 00:57:233195 // The proxy responds to the connect with a 407, using a persistent
3196 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3197 MockRead data_reads1[] = {
3198 // No credentials.
3199 MockRead(ASYNC, 1,
3200 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3201 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3202 "Proxy-Connection: keep-alive\r\n"
3203 "Content-Length: 10\r\n\r\n"),
3204 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013205
mmenked39192ee2015-12-09 00:57:233206 // Wrong credentials (wrong password).
3207 MockRead(ASYNC, 4,
3208 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3209 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3210 "Proxy-Connection: keep-alive\r\n"
3211 "Content-Length: 10\r\n\r\n"),
3212 // No response body because the test stops reading here.
3213 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3214 };
ttuttle34f63b52015-03-05 04:33:013215
mmenked39192ee2015-12-09 00:57:233216 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3217 arraysize(data_writes1));
3218 data1.set_busy_before_sync_reads(true);
3219 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013220
mmenked39192ee2015-12-09 00:57:233221 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013222
bnc691fda62016-08-12 00:43:163223 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013224 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013225
mmenked39192ee2015-12-09 00:57:233226 TestNetLogEntry::List entries;
3227 log.GetEntries(&entries);
3228 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003229 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3230 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233231 ExpectLogContainsSomewhere(
3232 entries, pos,
mikecirone8b85c432016-09-08 19:11:003233 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3234 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013235
bnc691fda62016-08-12 00:43:163236 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233237 ASSERT_TRUE(response);
3238 ASSERT_TRUE(response->headers);
3239 EXPECT_TRUE(response->headers->IsKeepAlive());
3240 EXPECT_EQ(407, response->headers->response_code());
3241 EXPECT_EQ(10, response->headers->GetContentLength());
3242 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3243 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013244
mmenked39192ee2015-12-09 00:57:233245 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013246
mmenked39192ee2015-12-09 00:57:233247 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163248 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3249 callback2.callback());
robpercival214763f2016-07-01 23:27:013250 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013251
bnc691fda62016-08-12 00:43:163252 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233253 ASSERT_TRUE(response);
3254 ASSERT_TRUE(response->headers);
3255 EXPECT_TRUE(response->headers->IsKeepAlive());
3256 EXPECT_EQ(407, response->headers->response_code());
3257 EXPECT_EQ(10, response->headers->GetContentLength());
3258 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3259 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013260
mmenked39192ee2015-12-09 00:57:233261 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3262 // out of scope.
3263 session->CloseAllConnections();
3264 }
ttuttle34f63b52015-03-05 04:33:013265}
3266
3267// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3268// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013269TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233270 // On the second pass, the body read of the auth challenge is synchronous, so
3271 // IsConnectedAndIdle returns false. The socket should still be drained and
3272 // reused. See http://crbug.com/544255.
3273 for (int i = 0; i < 2; ++i) {
3274 HttpRequestInfo request;
3275 request.method = "GET";
3276 request.url = GURL("https://www.example.org/");
3277 // Ensure that proxy authentication is attempted even
3278 // when the no authentication data flag is set.
3279 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3280
3281 // Configure against proxy server "myproxy:70".
3282 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3283 BoundTestNetLog log;
3284 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093285 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233286
bnc691fda62016-08-12 00:43:163287 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233288
3289 // Since we have proxy, should try to establish tunnel.
3290 MockWrite data_writes1[] = {
3291 MockWrite(ASYNC, 0,
3292 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3293 "Host: www.example.org:443\r\n"
3294 "Proxy-Connection: keep-alive\r\n\r\n"),
3295
bnc691fda62016-08-12 00:43:163296 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233297 // be issuing -- the final header line contains the credentials.
3298 MockWrite(ASYNC, 3,
3299 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3300 "Host: www.example.org:443\r\n"
3301 "Proxy-Connection: keep-alive\r\n"
3302 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3303 };
3304
3305 // The proxy responds to the connect with a 407, using a persistent
3306 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3307 MockRead data_reads1[] = {
3308 // No credentials.
3309 MockRead(ASYNC, 1,
3310 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3311 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3312 "Content-Length: 10\r\n\r\n"),
3313 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3314
3315 // Wrong credentials (wrong password).
3316 MockRead(ASYNC, 4,
3317 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3318 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3319 "Content-Length: 10\r\n\r\n"),
3320 // No response body because the test stops reading here.
3321 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3322 };
3323
3324 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3325 arraysize(data_writes1));
3326 data1.set_busy_before_sync_reads(true);
3327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3328
3329 TestCompletionCallback callback1;
3330
bnc691fda62016-08-12 00:43:163331 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013332 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233333
3334 TestNetLogEntry::List entries;
3335 log.GetEntries(&entries);
3336 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003337 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3338 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233339 ExpectLogContainsSomewhere(
3340 entries, pos,
mikecirone8b85c432016-09-08 19:11:003341 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3342 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233343
bnc691fda62016-08-12 00:43:163344 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233345 ASSERT_TRUE(response);
3346 ASSERT_TRUE(response->headers);
3347 EXPECT_TRUE(response->headers->IsKeepAlive());
3348 EXPECT_EQ(407, response->headers->response_code());
3349 EXPECT_EQ(10, response->headers->GetContentLength());
3350 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3351 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3352
3353 TestCompletionCallback callback2;
3354
3355 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163356 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3357 callback2.callback());
robpercival214763f2016-07-01 23:27:013358 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233359
bnc691fda62016-08-12 00:43:163360 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233361 ASSERT_TRUE(response);
3362 ASSERT_TRUE(response->headers);
3363 EXPECT_TRUE(response->headers->IsKeepAlive());
3364 EXPECT_EQ(407, response->headers->response_code());
3365 EXPECT_EQ(10, response->headers->GetContentLength());
3366 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3367 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3368
3369 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3370 // out of scope.
3371 session->CloseAllConnections();
3372 }
3373}
3374
3375// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3376// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3377// the case the server sends extra data on the original socket, so it can't be
3378// reused.
bncd16676a2016-07-20 16:23:013379TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273380 HttpRequestInfo request;
3381 request.method = "GET";
bncce36dca22015-04-21 22:11:233382 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273383 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293384 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273385
[email protected]2d2697f92009-02-18 21:00:323386 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233387 session_deps_.proxy_service =
3388 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513389 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073390 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323392
[email protected]2d2697f92009-02-18 21:00:323393 // Since we have proxy, should try to establish tunnel.
3394 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233395 MockWrite(ASYNC, 0,
3396 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173397 "Host: www.example.org:443\r\n"
3398 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233399 };
[email protected]2d2697f92009-02-18 21:00:323400
mmenked39192ee2015-12-09 00:57:233401 // The proxy responds to the connect with a 407, using a persistent, but sends
3402 // extra data, so the socket cannot be reused.
3403 MockRead data_reads1[] = {
3404 // No credentials.
3405 MockRead(ASYNC, 1,
3406 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3407 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3408 "Content-Length: 10\r\n\r\n"),
3409 MockRead(SYNCHRONOUS, 2, "0123456789"),
3410 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3411 };
3412
3413 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233414 // After calling trans->RestartWithAuth(), this is the request we should
3415 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233416 MockWrite(ASYNC, 0,
3417 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173418 "Host: www.example.org:443\r\n"
3419 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233420 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3421
3422 MockWrite(ASYNC, 2,
3423 "GET / HTTP/1.1\r\n"
3424 "Host: www.example.org\r\n"
3425 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323426 };
3427
mmenked39192ee2015-12-09 00:57:233428 MockRead data_reads2[] = {
3429 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323430
mmenked39192ee2015-12-09 00:57:233431 MockRead(ASYNC, 3,
3432 "HTTP/1.1 200 OK\r\n"
3433 "Content-Type: text/html; charset=iso-8859-1\r\n"
3434 "Content-Length: 5\r\n\r\n"),
3435 // No response body because the test stops reading here.
3436 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323437 };
3438
mmenked39192ee2015-12-09 00:57:233439 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3440 arraysize(data_writes1));
3441 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073442 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233443 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3444 arraysize(data_writes2));
3445 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3446 SSLSocketDataProvider ssl(ASYNC, OK);
3447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323448
[email protected]49639fa2011-12-20 23:22:413449 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323450
bnc87dcefc2017-05-25 12:47:583451 auto trans =
3452 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323453
mmenked39192ee2015-12-09 00:57:233454 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013455 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233456
mmenke43758e62015-05-04 21:09:463457 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403458 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393459 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003460 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3461 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393462 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403463 entries, pos,
mikecirone8b85c432016-09-08 19:11:003464 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3465 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323466
[email protected]1c773ea12009-04-28 19:58:423467 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243468 ASSERT_TRUE(response);
3469 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323470 EXPECT_TRUE(response->headers->IsKeepAlive());
3471 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423472 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043473 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323474
mmenked39192ee2015-12-09 00:57:233475 LoadTimingInfo load_timing_info;
3476 // CONNECT requests and responses are handled at the connect job level, so
3477 // the transaction does not yet have a connection.
3478 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3479
[email protected]49639fa2011-12-20 23:22:413480 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323481
mmenked39192ee2015-12-09 00:57:233482 rv =
3483 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013484 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323485
[email protected]2d2697f92009-02-18 21:00:323486 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233487 EXPECT_EQ(200, response->headers->response_code());
3488 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423489 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133490
mmenked39192ee2015-12-09 00:57:233491 // The password prompt info should not be set.
3492 EXPECT_FALSE(response->auth_challenge);
3493
3494 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3495 TestLoadTimingNotReusedWithPac(load_timing_info,
3496 CONNECT_TIMING_HAS_SSL_TIMES);
3497
3498 trans.reset();
[email protected]102e27c2011-02-23 01:01:313499 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323500}
3501
mmenkee71e15332015-10-07 16:39:543502// Test the case a proxy closes a socket while the challenge body is being
3503// drained.
bncd16676a2016-07-20 16:23:013504TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543505 HttpRequestInfo request;
3506 request.method = "GET";
3507 request.url = GURL("https://www.example.org/");
3508 // Ensure that proxy authentication is attempted even
3509 // when the no authentication data flag is set.
3510 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3511
3512 // Configure against proxy server "myproxy:70".
3513 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093514 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543515
bnc691fda62016-08-12 00:43:163516 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543517
3518 // Since we have proxy, should try to establish tunnel.
3519 MockWrite data_writes1[] = {
3520 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173521 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543522 "Proxy-Connection: keep-alive\r\n\r\n"),
3523 };
3524
3525 // The proxy responds to the connect with a 407, using a persistent
3526 // connection.
3527 MockRead data_reads1[] = {
3528 // No credentials.
3529 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3530 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3531 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3532 // Server hands up in the middle of the body.
3533 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3534 };
3535
3536 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163537 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543538 // be issuing -- the final header line contains the credentials.
3539 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173540 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543541 "Proxy-Connection: keep-alive\r\n"
3542 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3543
3544 MockWrite("GET / HTTP/1.1\r\n"
3545 "Host: www.example.org\r\n"
3546 "Connection: keep-alive\r\n\r\n"),
3547 };
3548
3549 MockRead data_reads2[] = {
3550 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3551
3552 MockRead("HTTP/1.1 200 OK\r\n"),
3553 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3554 MockRead("Content-Length: 5\r\n\r\n"),
3555 MockRead(SYNCHRONOUS, "hello"),
3556 };
3557
3558 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3559 data_writes1, arraysize(data_writes1));
3560 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3561 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3562 data_writes2, arraysize(data_writes2));
3563 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3564 SSLSocketDataProvider ssl(ASYNC, OK);
3565 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3566
3567 TestCompletionCallback callback;
3568
tfarina42834112016-09-22 13:38:203569 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013570 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543571
bnc691fda62016-08-12 00:43:163572 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543573 ASSERT_TRUE(response);
3574 ASSERT_TRUE(response->headers);
3575 EXPECT_TRUE(response->headers->IsKeepAlive());
3576 EXPECT_EQ(407, response->headers->response_code());
3577 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3578
bnc691fda62016-08-12 00:43:163579 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013580 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543581
bnc691fda62016-08-12 00:43:163582 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543583 ASSERT_TRUE(response);
3584 ASSERT_TRUE(response->headers);
3585 EXPECT_TRUE(response->headers->IsKeepAlive());
3586 EXPECT_EQ(200, response->headers->response_code());
3587 std::string body;
bnc691fda62016-08-12 00:43:163588 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543589 EXPECT_EQ("hello", body);
3590}
3591
[email protected]a8e9b162009-03-12 00:06:443592// Test that we don't read the response body when we fail to establish a tunnel,
3593// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013594TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273595 HttpRequestInfo request;
3596 request.method = "GET";
bncce36dca22015-04-21 22:11:233597 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273598
[email protected]a8e9b162009-03-12 00:06:443599 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033600 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443601
danakj1fd259a02016-04-16 03:17:093602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443603
bnc691fda62016-08-12 00:43:163604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443605
[email protected]a8e9b162009-03-12 00:06:443606 // Since we have proxy, should try to establish tunnel.
3607 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173608 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3609 "Host: www.example.org:443\r\n"
3610 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443611 };
3612
3613 // The proxy responds to the connect with a 407.
3614 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243615 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3616 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3617 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233618 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243619 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443620 };
3621
[email protected]31a2bfe2010-02-09 08:03:393622 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3623 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073624 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443625
[email protected]49639fa2011-12-20 23:22:413626 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443627
tfarina42834112016-09-22 13:38:203628 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013629 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443630
3631 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013632 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443633
bnc691fda62016-08-12 00:43:163634 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243635 ASSERT_TRUE(response);
3636 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443637 EXPECT_TRUE(response->headers->IsKeepAlive());
3638 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423639 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443640
3641 std::string response_data;
bnc691fda62016-08-12 00:43:163642 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013643 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183644
3645 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313646 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443647}
3648
ttuttle7933c112015-01-06 00:55:243649// Test that we don't pass extraneous headers from the proxy's response to the
3650// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013651TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243652 HttpRequestInfo request;
3653 request.method = "GET";
bncce36dca22015-04-21 22:11:233654 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243655
3656 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033657 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243658
danakj1fd259a02016-04-16 03:17:093659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243660
bnc691fda62016-08-12 00:43:163661 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243662
3663 // Since we have proxy, should try to establish tunnel.
3664 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173665 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3666 "Host: www.example.org:443\r\n"
3667 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243668 };
3669
3670 // The proxy responds to the connect with a 407.
3671 MockRead data_reads[] = {
3672 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3673 MockRead("X-Foo: bar\r\n"),
3674 MockRead("Set-Cookie: foo=bar\r\n"),
3675 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3676 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233677 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243678 };
3679
3680 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3681 arraysize(data_writes));
3682 session_deps_.socket_factory->AddSocketDataProvider(&data);
3683
3684 TestCompletionCallback callback;
3685
tfarina42834112016-09-22 13:38:203686 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013687 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243688
3689 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013690 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243691
bnc691fda62016-08-12 00:43:163692 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243693 ASSERT_TRUE(response);
3694 ASSERT_TRUE(response->headers);
3695 EXPECT_TRUE(response->headers->IsKeepAlive());
3696 EXPECT_EQ(407, response->headers->response_code());
3697 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3698 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3699 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3700
3701 std::string response_data;
bnc691fda62016-08-12 00:43:163702 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013703 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243704
3705 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3706 session->CloseAllConnections();
3707}
3708
[email protected]8fdbcd22010-05-05 02:54:523709// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3710// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013711TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523712 HttpRequestInfo request;
3713 request.method = "GET";
bncce36dca22015-04-21 22:11:233714 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523715
[email protected]cb9bf6ca2011-01-28 13:15:273716 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273719
[email protected]8fdbcd22010-05-05 02:54:523720 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233721 MockWrite(
3722 "GET / HTTP/1.1\r\n"
3723 "Host: www.example.org\r\n"
3724 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523725 };
3726
3727 MockRead data_reads1[] = {
3728 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3729 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3730 // Large content-length -- won't matter, as connection will be reset.
3731 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063732 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523733 };
3734
3735 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3736 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073737 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523738
[email protected]49639fa2011-12-20 23:22:413739 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523740
tfarina42834112016-09-22 13:38:203741 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523743
3744 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013745 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523746}
3747
[email protected]7a67a8152010-11-05 18:31:103748// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3749// through a non-authenticating proxy. The request should fail with
3750// ERR_UNEXPECTED_PROXY_AUTH.
3751// Note that it is impossible to detect if an HTTP server returns a 407 through
3752// a non-authenticating proxy - there is nothing to indicate whether the
3753// response came from the proxy or the server, so it is treated as if the proxy
3754// issued the challenge.
bncd16676a2016-07-20 16:23:013755TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273756 HttpRequestInfo request;
3757 request.method = "GET";
bncce36dca22015-04-21 22:11:233758 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273759
rdsmith82957ad2015-09-16 19:42:033760 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513761 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073762 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103764
[email protected]7a67a8152010-11-05 18:31:103765 // Since we have proxy, should try to establish tunnel.
3766 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173767 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3768 "Host: www.example.org:443\r\n"
3769 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103770
rsleevidb16bb02015-11-12 23:47:173771 MockWrite("GET / HTTP/1.1\r\n"
3772 "Host: www.example.org\r\n"
3773 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103774 };
3775
3776 MockRead data_reads1[] = {
3777 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3778
3779 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3780 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3781 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063782 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103783 };
3784
3785 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3786 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073787 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063788 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073789 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103790
[email protected]49639fa2011-12-20 23:22:413791 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103792
bnc691fda62016-08-12 00:43:163793 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103794
bnc691fda62016-08-12 00:43:163795 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103797
3798 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013799 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463800 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403801 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103802 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003803 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3804 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103805 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403806 entries, pos,
mikecirone8b85c432016-09-08 19:11:003807 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3808 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103809}
[email protected]2df19bb2010-08-25 20:13:463810
mmenke2a1781d2015-10-07 19:25:333811// Test a proxy auth scheme that allows default credentials and a proxy server
3812// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013813TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333814 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3815 HttpRequestInfo request;
3816 request.method = "GET";
3817 request.url = GURL("https://www.example.org/");
3818
3819 // Configure against proxy server "myproxy:70".
3820 session_deps_.proxy_service =
3821 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3822
bnc87dcefc2017-05-25 12:47:583823 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333824 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583825 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333826 mock_handler->set_allows_default_credentials(true);
3827 auth_handler_factory->AddMockHandler(mock_handler.release(),
3828 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483829 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333830
3831 // Add NetLog just so can verify load timing information gets a NetLog ID.
3832 NetLog net_log;
3833 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093834 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333835
3836 // Since we have proxy, should try to establish tunnel.
3837 MockWrite data_writes1[] = {
3838 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173839 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333840 "Proxy-Connection: keep-alive\r\n\r\n"),
3841 };
3842
3843 // The proxy responds to the connect with a 407, using a non-persistent
3844 // connection.
3845 MockRead data_reads1[] = {
3846 // No credentials.
3847 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3848 MockRead("Proxy-Authenticate: Mock\r\n"),
3849 MockRead("Proxy-Connection: close\r\n\r\n"),
3850 };
3851
3852 // Since the first connection couldn't be reused, need to establish another
3853 // once given credentials.
3854 MockWrite data_writes2[] = {
3855 // After calling trans->RestartWithAuth(), this is the request we should
3856 // be issuing -- the final header line contains the credentials.
3857 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173858 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333859 "Proxy-Connection: keep-alive\r\n"
3860 "Proxy-Authorization: auth_token\r\n\r\n"),
3861
3862 MockWrite("GET / HTTP/1.1\r\n"
3863 "Host: www.example.org\r\n"
3864 "Connection: keep-alive\r\n\r\n"),
3865 };
3866
3867 MockRead data_reads2[] = {
3868 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3869
3870 MockRead("HTTP/1.1 200 OK\r\n"),
3871 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3872 MockRead("Content-Length: 5\r\n\r\n"),
3873 MockRead(SYNCHRONOUS, "hello"),
3874 };
3875
3876 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3877 data_writes1, arraysize(data_writes1));
3878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3879 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3880 data_writes2, arraysize(data_writes2));
3881 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3882 SSLSocketDataProvider ssl(ASYNC, OK);
3883 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3884
bnc87dcefc2017-05-25 12:47:583885 auto trans =
3886 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333887
3888 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203889 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013890 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333891
3892 const HttpResponseInfo* response = trans->GetResponseInfo();
3893 ASSERT_TRUE(response);
3894 ASSERT_TRUE(response->headers);
3895 EXPECT_FALSE(response->headers->IsKeepAlive());
3896 EXPECT_EQ(407, response->headers->response_code());
3897 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3898 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523899 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333900
3901 LoadTimingInfo load_timing_info;
3902 // CONNECT requests and responses are handled at the connect job level, so
3903 // the transaction does not yet have a connection.
3904 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3905
3906 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013907 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333908 response = trans->GetResponseInfo();
3909 ASSERT_TRUE(response);
3910 ASSERT_TRUE(response->headers);
3911 EXPECT_TRUE(response->headers->IsKeepAlive());
3912 EXPECT_EQ(200, response->headers->response_code());
3913 EXPECT_EQ(5, response->headers->GetContentLength());
3914 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3915
3916 // The password prompt info should not be set.
3917 EXPECT_FALSE(response->auth_challenge);
3918
3919 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3920 TestLoadTimingNotReusedWithPac(load_timing_info,
3921 CONNECT_TIMING_HAS_SSL_TIMES);
3922
3923 trans.reset();
3924 session->CloseAllConnections();
3925}
3926
3927// Test a proxy auth scheme that allows default credentials and a proxy server
3928// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013929TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333930 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3931 HttpRequestInfo request;
3932 request.method = "GET";
3933 request.url = GURL("https://www.example.org/");
3934
3935 // Configure against proxy server "myproxy:70".
3936 session_deps_.proxy_service =
3937 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3938
bnc87dcefc2017-05-25 12:47:583939 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333940 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583941 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333942 mock_handler->set_allows_default_credentials(true);
3943 auth_handler_factory->AddMockHandler(mock_handler.release(),
3944 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483945 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333946
3947 // Add NetLog just so can verify load timing information gets a NetLog ID.
3948 NetLog net_log;
3949 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093950 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333951
3952 // Should try to establish tunnel.
3953 MockWrite data_writes1[] = {
3954 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173955 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333956 "Proxy-Connection: keep-alive\r\n\r\n"),
3957
3958 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173959 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333960 "Proxy-Connection: keep-alive\r\n"
3961 "Proxy-Authorization: auth_token\r\n\r\n"),
3962 };
3963
3964 // The proxy responds to the connect with a 407, using a non-persistent
3965 // connection.
3966 MockRead data_reads1[] = {
3967 // No credentials.
3968 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3969 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3970 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3971 };
3972
3973 // Since the first connection was closed, need to establish another once given
3974 // credentials.
3975 MockWrite data_writes2[] = {
3976 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173977 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333978 "Proxy-Connection: keep-alive\r\n"
3979 "Proxy-Authorization: auth_token\r\n\r\n"),
3980
3981 MockWrite("GET / HTTP/1.1\r\n"
3982 "Host: www.example.org\r\n"
3983 "Connection: keep-alive\r\n\r\n"),
3984 };
3985
3986 MockRead data_reads2[] = {
3987 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3988
3989 MockRead("HTTP/1.1 200 OK\r\n"),
3990 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3991 MockRead("Content-Length: 5\r\n\r\n"),
3992 MockRead(SYNCHRONOUS, "hello"),
3993 };
3994
3995 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3996 data_writes1, arraysize(data_writes1));
3997 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3998 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3999 data_writes2, arraysize(data_writes2));
4000 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4001 SSLSocketDataProvider ssl(ASYNC, OK);
4002 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4003
bnc87dcefc2017-05-25 12:47:584004 auto trans =
4005 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334006
4007 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204008 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014009 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334010
4011 const HttpResponseInfo* response = trans->GetResponseInfo();
4012 ASSERT_TRUE(response);
4013 ASSERT_TRUE(response->headers);
4014 EXPECT_TRUE(response->headers->IsKeepAlive());
4015 EXPECT_EQ(407, response->headers->response_code());
4016 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4017 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4018 EXPECT_FALSE(response->auth_challenge);
4019
4020 LoadTimingInfo load_timing_info;
4021 // CONNECT requests and responses are handled at the connect job level, so
4022 // the transaction does not yet have a connection.
4023 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4024
4025 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014026 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334027
4028 response = trans->GetResponseInfo();
4029 ASSERT_TRUE(response);
4030 ASSERT_TRUE(response->headers);
4031 EXPECT_TRUE(response->headers->IsKeepAlive());
4032 EXPECT_EQ(200, response->headers->response_code());
4033 EXPECT_EQ(5, response->headers->GetContentLength());
4034 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4035
4036 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524037 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334038
4039 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4040 TestLoadTimingNotReusedWithPac(load_timing_info,
4041 CONNECT_TIMING_HAS_SSL_TIMES);
4042
4043 trans.reset();
4044 session->CloseAllConnections();
4045}
4046
4047// Test a proxy auth scheme that allows default credentials and a proxy server
4048// that hangs up when credentials are initially sent, and hangs up again when
4049// they are retried.
bncd16676a2016-07-20 16:23:014050TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334051 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4052 HttpRequestInfo request;
4053 request.method = "GET";
4054 request.url = GURL("https://www.example.org/");
4055
4056 // Configure against proxy server "myproxy:70".
4057 session_deps_.proxy_service =
4058 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4059
bnc87dcefc2017-05-25 12:47:584060 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334061 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584062 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334063 mock_handler->set_allows_default_credentials(true);
4064 auth_handler_factory->AddMockHandler(mock_handler.release(),
4065 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484066 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334067
4068 // Add NetLog just so can verify load timing information gets a NetLog ID.
4069 NetLog net_log;
4070 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094071 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334072
4073 // Should try to establish tunnel.
4074 MockWrite data_writes1[] = {
4075 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174076 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334077 "Proxy-Connection: keep-alive\r\n\r\n"),
4078
4079 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174080 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334081 "Proxy-Connection: keep-alive\r\n"
4082 "Proxy-Authorization: auth_token\r\n\r\n"),
4083 };
4084
4085 // The proxy responds to the connect with a 407, and then hangs up after the
4086 // second request is sent.
4087 MockRead data_reads1[] = {
4088 // No credentials.
4089 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4090 MockRead("Content-Length: 0\r\n"),
4091 MockRead("Proxy-Connection: keep-alive\r\n"),
4092 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4093 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4094 };
4095
4096 // HttpNetworkTransaction sees a reused connection that was closed with
4097 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4098 // request.
4099 MockWrite data_writes2[] = {
4100 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174101 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334102 "Proxy-Connection: keep-alive\r\n\r\n"),
4103 };
4104
4105 // The proxy, having had more than enough of us, just hangs up.
4106 MockRead data_reads2[] = {
4107 // No credentials.
4108 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4109 };
4110
4111 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4112 data_writes1, arraysize(data_writes1));
4113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4114 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4115 data_writes2, arraysize(data_writes2));
4116 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4117
bnc87dcefc2017-05-25 12:47:584118 auto trans =
4119 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334120
4121 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204122 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014123 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334124
4125 const HttpResponseInfo* response = trans->GetResponseInfo();
4126 ASSERT_TRUE(response);
4127 ASSERT_TRUE(response->headers);
4128 EXPECT_TRUE(response->headers->IsKeepAlive());
4129 EXPECT_EQ(407, response->headers->response_code());
4130 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4131 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4132 EXPECT_FALSE(response->auth_challenge);
4133
4134 LoadTimingInfo load_timing_info;
4135 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4136
4137 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014138 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334139
4140 trans.reset();
4141 session->CloseAllConnections();
4142}
4143
4144// Test a proxy auth scheme that allows default credentials and a proxy server
4145// that hangs up when credentials are initially sent, and sends a challenge
4146// again they are retried.
bncd16676a2016-07-20 16:23:014147TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334148 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4149 HttpRequestInfo request;
4150 request.method = "GET";
4151 request.url = GURL("https://www.example.org/");
4152
4153 // Configure against proxy server "myproxy:70".
4154 session_deps_.proxy_service =
4155 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4156
bnc87dcefc2017-05-25 12:47:584157 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334158 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584159 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334160 mock_handler->set_allows_default_credentials(true);
4161 auth_handler_factory->AddMockHandler(mock_handler.release(),
4162 HttpAuth::AUTH_PROXY);
4163 // Add another handler for the second challenge. It supports default
4164 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584165 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334166 mock_handler->set_allows_default_credentials(true);
4167 auth_handler_factory->AddMockHandler(mock_handler.release(),
4168 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484169 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334170
4171 // Add NetLog just so can verify load timing information gets a NetLog ID.
4172 NetLog net_log;
4173 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094174 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334175
4176 // Should try to establish tunnel.
4177 MockWrite data_writes1[] = {
4178 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174179 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334180 "Proxy-Connection: keep-alive\r\n\r\n"),
4181 };
4182
4183 // The proxy responds to the connect with a 407, using a non-persistent
4184 // connection.
4185 MockRead data_reads1[] = {
4186 // No credentials.
4187 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4188 MockRead("Proxy-Authenticate: Mock\r\n"),
4189 MockRead("Proxy-Connection: close\r\n\r\n"),
4190 };
4191
4192 // Since the first connection was closed, need to establish another once given
4193 // credentials.
4194 MockWrite data_writes2[] = {
4195 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174196 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334197 "Proxy-Connection: keep-alive\r\n"
4198 "Proxy-Authorization: auth_token\r\n\r\n"),
4199 };
4200
4201 MockRead data_reads2[] = {
4202 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4203 MockRead("Proxy-Authenticate: Mock\r\n"),
4204 MockRead("Proxy-Connection: close\r\n\r\n"),
4205 };
4206
4207 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4208 data_writes1, arraysize(data_writes1));
4209 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4210 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4211 data_writes2, arraysize(data_writes2));
4212 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4213 SSLSocketDataProvider ssl(ASYNC, OK);
4214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4215
bnc87dcefc2017-05-25 12:47:584216 auto trans =
4217 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334218
4219 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204220 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014221 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334222
4223 const HttpResponseInfo* response = trans->GetResponseInfo();
4224 ASSERT_TRUE(response);
4225 ASSERT_TRUE(response->headers);
4226 EXPECT_EQ(407, response->headers->response_code());
4227 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4228 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4229 EXPECT_FALSE(response->auth_challenge);
4230
4231 LoadTimingInfo load_timing_info;
4232 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4233
4234 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014235 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334236 response = trans->GetResponseInfo();
4237 ASSERT_TRUE(response);
4238 ASSERT_TRUE(response->headers);
4239 EXPECT_EQ(407, response->headers->response_code());
4240 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4241 EXPECT_TRUE(response->auth_challenge);
4242
4243 trans.reset();
4244 session->CloseAllConnections();
4245}
4246
asankae2257db2016-10-11 22:03:164247// A more nuanced test than GenerateAuthToken test which asserts that
4248// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4249// unnecessarily invalidated, and that if the server co-operates, the
4250// authentication handshake can continue with the same scheme but with a
4251// different identity.
4252TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4253 HttpRequestInfo request;
4254 request.method = "GET";
4255 request.url = GURL("http://www.example.org/");
4256
bnc87dcefc2017-05-25 12:47:584257 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164258 auth_handler_factory->set_do_init_from_challenge(true);
4259
4260 // First handler. Uses default credentials, but barfs at generate auth token.
bnc87dcefc2017-05-25 12:47:584261 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164262 mock_handler->set_allows_default_credentials(true);
4263 mock_handler->set_allows_explicit_credentials(true);
4264 mock_handler->set_connection_based(true);
4265 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4266 auth_handler_factory->AddMockHandler(mock_handler.release(),
4267 HttpAuth::AUTH_SERVER);
4268
4269 // Add another handler for the second challenge. It supports default
4270 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584271 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164272 mock_handler->set_allows_default_credentials(true);
4273 mock_handler->set_allows_explicit_credentials(true);
4274 mock_handler->set_connection_based(true);
4275 auth_handler_factory->AddMockHandler(mock_handler.release(),
4276 HttpAuth::AUTH_SERVER);
4277 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4278
4279 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4280
4281 MockWrite data_writes1[] = {
4282 MockWrite("GET / HTTP/1.1\r\n"
4283 "Host: www.example.org\r\n"
4284 "Connection: keep-alive\r\n\r\n"),
4285 };
4286
4287 MockRead data_reads1[] = {
4288 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4289 "WWW-Authenticate: Mock\r\n"
4290 "Connection: keep-alive\r\n\r\n"),
4291 };
4292
4293 // Identical to data_writes1[]. The AuthHandler encounters a
4294 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4295 // transaction procceds without an authorization header.
4296 MockWrite data_writes2[] = {
4297 MockWrite("GET / HTTP/1.1\r\n"
4298 "Host: www.example.org\r\n"
4299 "Connection: keep-alive\r\n\r\n"),
4300 };
4301
4302 MockRead data_reads2[] = {
4303 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4304 "WWW-Authenticate: Mock\r\n"
4305 "Connection: keep-alive\r\n\r\n"),
4306 };
4307
4308 MockWrite data_writes3[] = {
4309 MockWrite("GET / HTTP/1.1\r\n"
4310 "Host: www.example.org\r\n"
4311 "Connection: keep-alive\r\n"
4312 "Authorization: auth_token\r\n\r\n"),
4313 };
4314
4315 MockRead data_reads3[] = {
4316 MockRead("HTTP/1.1 200 OK\r\n"
4317 "Content-Length: 5\r\n"
4318 "Content-Type: text/plain\r\n"
4319 "Connection: keep-alive\r\n\r\n"
4320 "Hello"),
4321 };
4322
4323 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4324 data_writes1, arraysize(data_writes1));
4325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4326
4327 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4328 data_writes2, arraysize(data_writes2));
4329 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4330
4331 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4332 data_writes3, arraysize(data_writes3));
4333 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4334
bnc87dcefc2017-05-25 12:47:584335 auto trans =
4336 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164337
4338 TestCompletionCallback callback;
4339 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4340 EXPECT_THAT(callback.GetResult(rv), IsOk());
4341
4342 const HttpResponseInfo* response = trans->GetResponseInfo();
4343 ASSERT_TRUE(response);
4344 ASSERT_TRUE(response->headers);
4345 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4346
4347 // The following three tests assert that an authentication challenge was
4348 // received and that the stack is ready to respond to the challenge using
4349 // ambient credentials.
4350 EXPECT_EQ(401, response->headers->response_code());
4351 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4352 EXPECT_FALSE(response->auth_challenge);
4353
4354 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4355 EXPECT_THAT(callback.GetResult(rv), IsOk());
4356 response = trans->GetResponseInfo();
4357 ASSERT_TRUE(response);
4358 ASSERT_TRUE(response->headers);
4359
4360 // The following three tests assert that an authentication challenge was
4361 // received and that the stack needs explicit credentials before it is ready
4362 // to respond to the challenge.
4363 EXPECT_EQ(401, response->headers->response_code());
4364 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4365 EXPECT_TRUE(response->auth_challenge);
4366
4367 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4368 EXPECT_THAT(callback.GetResult(rv), IsOk());
4369 response = trans->GetResponseInfo();
4370 ASSERT_TRUE(response);
4371 ASSERT_TRUE(response->headers);
4372 EXPECT_EQ(200, response->headers->response_code());
4373
4374 trans.reset();
4375 session->CloseAllConnections();
4376}
4377
[email protected]029c83b62013-01-24 05:28:204378// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014379TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204380 HttpRequestInfo request1;
4381 request1.method = "GET";
bncce36dca22015-04-21 22:11:234382 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204383
4384 HttpRequestInfo request2;
4385 request2.method = "GET";
bncce36dca22015-04-21 22:11:234386 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204387
4388 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134389 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514390 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074391 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204393
4394 // Since we have proxy, should try to establish tunnel.
4395 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174396 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4397 "Host: www.example.org:443\r\n"
4398 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204399
rsleevidb16bb02015-11-12 23:47:174400 MockWrite("GET /1 HTTP/1.1\r\n"
4401 "Host: www.example.org\r\n"
4402 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204403
rsleevidb16bb02015-11-12 23:47:174404 MockWrite("GET /2 HTTP/1.1\r\n"
4405 "Host: www.example.org\r\n"
4406 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204407 };
4408
4409 // The proxy responds to the connect with a 407, using a persistent
4410 // connection.
4411 MockRead data_reads1[] = {
4412 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4413
4414 MockRead("HTTP/1.1 200 OK\r\n"),
4415 MockRead("Content-Length: 1\r\n\r\n"),
4416 MockRead(SYNCHRONOUS, "1"),
4417
4418 MockRead("HTTP/1.1 200 OK\r\n"),
4419 MockRead("Content-Length: 2\r\n\r\n"),
4420 MockRead(SYNCHRONOUS, "22"),
4421 };
4422
4423 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4424 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074425 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204426 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204428
4429 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584430 auto trans1 =
4431 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204432
4433 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204435
4436 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014437 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204438
4439 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524440 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474441 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524442 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204443 EXPECT_EQ(1, response1->headers->GetContentLength());
4444
4445 LoadTimingInfo load_timing_info1;
4446 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4447 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4448
4449 trans1.reset();
4450
4451 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584452 auto trans2 =
4453 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204454
4455 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204457
4458 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014459 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204460
4461 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524462 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474463 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524464 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204465 EXPECT_EQ(2, response2->headers->GetContentLength());
4466
4467 LoadTimingInfo load_timing_info2;
4468 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4469 TestLoadTimingReused(load_timing_info2);
4470
4471 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4472
4473 trans2.reset();
4474 session->CloseAllConnections();
4475}
4476
4477// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014478TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204479 HttpRequestInfo request1;
4480 request1.method = "GET";
bncce36dca22015-04-21 22:11:234481 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204482
4483 HttpRequestInfo request2;
4484 request2.method = "GET";
bncce36dca22015-04-21 22:11:234485 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204486
4487 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034488 session_deps_.proxy_service =
4489 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514490 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074491 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094492 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204493
4494 // Since we have proxy, should try to establish tunnel.
4495 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174496 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4497 "Host: www.example.org:443\r\n"
4498 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204499
rsleevidb16bb02015-11-12 23:47:174500 MockWrite("GET /1 HTTP/1.1\r\n"
4501 "Host: www.example.org\r\n"
4502 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204503
rsleevidb16bb02015-11-12 23:47:174504 MockWrite("GET /2 HTTP/1.1\r\n"
4505 "Host: www.example.org\r\n"
4506 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204507 };
4508
4509 // The proxy responds to the connect with a 407, using a persistent
4510 // connection.
4511 MockRead data_reads1[] = {
4512 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4513
4514 MockRead("HTTP/1.1 200 OK\r\n"),
4515 MockRead("Content-Length: 1\r\n\r\n"),
4516 MockRead(SYNCHRONOUS, "1"),
4517
4518 MockRead("HTTP/1.1 200 OK\r\n"),
4519 MockRead("Content-Length: 2\r\n\r\n"),
4520 MockRead(SYNCHRONOUS, "22"),
4521 };
4522
4523 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4524 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074525 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204526 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074527 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204528
4529 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584530 auto trans1 =
4531 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204532
4533 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204535
4536 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014537 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204538
4539 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524540 ASSERT_TRUE(response1);
4541 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204542 EXPECT_EQ(1, response1->headers->GetContentLength());
4543
4544 LoadTimingInfo load_timing_info1;
4545 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4546 TestLoadTimingNotReusedWithPac(load_timing_info1,
4547 CONNECT_TIMING_HAS_SSL_TIMES);
4548
4549 trans1.reset();
4550
4551 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584552 auto trans2 =
4553 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204554
4555 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204557
4558 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014559 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204560
4561 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524562 ASSERT_TRUE(response2);
4563 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204564 EXPECT_EQ(2, response2->headers->GetContentLength());
4565
4566 LoadTimingInfo load_timing_info2;
4567 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4568 TestLoadTimingReusedWithPac(load_timing_info2);
4569
4570 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4571
4572 trans2.reset();
4573 session->CloseAllConnections();
4574}
4575
[email protected]2df19bb2010-08-25 20:13:464576// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014577TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274578 HttpRequestInfo request;
4579 request.method = "GET";
bncce36dca22015-04-21 22:11:234580 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274581
[email protected]2df19bb2010-08-25 20:13:464582 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034583 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514584 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074585 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094586 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464587
[email protected]2df19bb2010-08-25 20:13:464588 // Since we have proxy, should use full url
4589 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234590 MockWrite(
4591 "GET http://www.example.org/ HTTP/1.1\r\n"
4592 "Host: www.example.org\r\n"
4593 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464594 };
4595
4596 MockRead data_reads1[] = {
4597 MockRead("HTTP/1.1 200 OK\r\n"),
4598 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4599 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064600 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464601 };
4602
4603 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4604 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074605 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064606 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074607 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464608
[email protected]49639fa2011-12-20 23:22:414609 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464610
bnc691fda62016-08-12 00:43:164611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504612
bnc691fda62016-08-12 00:43:164613 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014614 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464615
4616 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014617 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464618
[email protected]58e32bb2013-01-21 18:23:254619 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164620 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254621 TestLoadTimingNotReused(load_timing_info,
4622 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4623
bnc691fda62016-08-12 00:43:164624 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524625 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464626
tbansal2ecbbc72016-10-06 17:15:474627 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464628 EXPECT_TRUE(response->headers->IsKeepAlive());
4629 EXPECT_EQ(200, response->headers->response_code());
4630 EXPECT_EQ(100, response->headers->GetContentLength());
4631 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4632
4633 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524634 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464635}
4636
[email protected]7642b5ae2010-09-01 20:55:174637// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014638TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274639 HttpRequestInfo request;
4640 request.method = "GET";
bncce36dca22015-04-21 22:11:234641 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274642
[email protected]7642b5ae2010-09-01 20:55:174643 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034644 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514645 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074646 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174648
bncce36dca22015-04-21 22:11:234649 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414650 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454651 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414652 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174653
bnc42331402016-07-25 13:36:154654 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414655 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174656 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414657 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174658 };
4659
rch8e6c6c42015-05-01 14:05:134660 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4661 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074662 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174663
[email protected]8ddf8322012-02-23 18:08:064664 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364665 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074666 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174667
[email protected]49639fa2011-12-20 23:22:414668 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174669
bnc691fda62016-08-12 00:43:164670 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504671
bnc691fda62016-08-12 00:43:164672 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174674
4675 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014676 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174677
[email protected]58e32bb2013-01-21 18:23:254678 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164679 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254680 TestLoadTimingNotReused(load_timing_info,
4681 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4682
bnc691fda62016-08-12 00:43:164683 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524684 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474685 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524686 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024687 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174688
4689 std::string response_data;
bnc691fda62016-08-12 00:43:164690 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234691 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174692}
4693
[email protected]1c173852014-06-19 12:51:504694// Verifies that a session which races and wins against the owning transaction
4695// (completing prior to host resolution), doesn't fail the transaction.
4696// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014697TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504698 HttpRequestInfo request;
4699 request.method = "GET";
bncce36dca22015-04-21 22:11:234700 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504701
4702 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034703 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514704 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504705 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094706 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504707
bncce36dca22015-04-21 22:11:234708 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414709 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454710 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414711 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504712
bnc42331402016-07-25 13:36:154713 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414714 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504715 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414716 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504717 };
4718
rch8e6c6c42015-05-01 14:05:134719 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4720 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504721 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4722
4723 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364724 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4726
4727 TestCompletionCallback callback1;
4728
bnc691fda62016-08-12 00:43:164729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504730
4731 // Stall the hostname resolution begun by the transaction.
4732 session_deps_.host_resolver->set_synchronous_mode(false);
4733 session_deps_.host_resolver->set_ondemand_mode(true);
4734
bnc691fda62016-08-12 00:43:164735 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504737
4738 // Race a session to the proxy, which completes first.
4739 session_deps_.host_resolver->set_ondemand_mode(false);
4740 SpdySessionKey key(
4741 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4742 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424743 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504744
4745 // Unstall the resolution begun by the transaction.
4746 session_deps_.host_resolver->set_ondemand_mode(true);
4747 session_deps_.host_resolver->ResolveAllPending();
4748
4749 EXPECT_FALSE(callback1.have_result());
4750 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014751 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504752
bnc691fda62016-08-12 00:43:164753 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524754 ASSERT_TRUE(response);
4755 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024756 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504757
4758 std::string response_data;
bnc691fda62016-08-12 00:43:164759 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504760 EXPECT_EQ(kUploadData, response_data);
4761}
4762
[email protected]dc7bd1c52010-11-12 00:01:134763// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014764TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274765 HttpRequestInfo request;
4766 request.method = "GET";
bncce36dca22015-04-21 22:11:234767 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274768
[email protected]79cb5c12011-09-12 13:12:044769 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034770 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514771 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074772 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134774
[email protected]dc7bd1c52010-11-12 00:01:134775 // The first request will be a bare GET, the second request will be a
4776 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454777 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414778 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494779 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384780 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134781 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464782 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134783 };
bncdf80d44fd2016-07-15 20:27:414784 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4785 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4786 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134787 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414788 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134789 };
4790
4791 // The first response is a 407 proxy authentication challenge, and the second
4792 // response will be a 200 response since the second request includes a valid
4793 // Authorization header.
4794 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464795 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134796 };
bnc42331402016-07-25 13:36:154797 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234798 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414799 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4800 SpdySerializedFrame body_authentication(
4801 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154802 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414803 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134804 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414805 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464806 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414807 CreateMockRead(resp_data, 4),
4808 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134809 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134810 };
4811
rch8e6c6c42015-05-01 14:05:134812 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4813 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074814 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134815
[email protected]8ddf8322012-02-23 18:08:064816 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364817 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074818 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134819
[email protected]49639fa2011-12-20 23:22:414820 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134821
bnc691fda62016-08-12 00:43:164822 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134823
bnc691fda62016-08-12 00:43:164824 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134826
4827 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014828 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134829
bnc691fda62016-08-12 00:43:164830 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134831
wezca1070932016-05-26 20:30:524832 ASSERT_TRUE(response);
4833 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134834 EXPECT_EQ(407, response->headers->response_code());
4835 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434836 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134837
[email protected]49639fa2011-12-20 23:22:414838 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134839
bnc691fda62016-08-12 00:43:164840 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134842
4843 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014844 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134845
bnc691fda62016-08-12 00:43:164846 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134847
wezca1070932016-05-26 20:30:524848 ASSERT_TRUE(response_restart);
4849 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134850 EXPECT_EQ(200, response_restart->headers->response_code());
4851 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524852 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134853}
4854
[email protected]d9da5fe2010-10-13 22:37:164855// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014856TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274857 HttpRequestInfo request;
4858 request.method = "GET";
bncce36dca22015-04-21 22:11:234859 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274860
[email protected]d9da5fe2010-10-13 22:37:164861 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034862 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514863 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074864 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094865 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164866
bnc691fda62016-08-12 00:43:164867 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164868
bncce36dca22015-04-21 22:11:234869 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414870 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234871 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4872 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164873
bncce36dca22015-04-21 22:11:234874 const char get[] =
4875 "GET / HTTP/1.1\r\n"
4876 "Host: www.example.org\r\n"
4877 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414878 SpdySerializedFrame wrapped_get(
4879 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154880 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164881 const char resp[] = "HTTP/1.1 200 OK\r\n"
4882 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414883 SpdySerializedFrame wrapped_get_resp(
4884 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4885 SpdySerializedFrame wrapped_body(
4886 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4887 SpdySerializedFrame window_update(
4888 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044889
4890 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414891 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4892 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044893 };
4894
[email protected]d9da5fe2010-10-13 22:37:164895 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414896 CreateMockRead(conn_resp, 1, ASYNC),
4897 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4898 CreateMockRead(wrapped_body, 4, ASYNC),
4899 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134900 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164901 };
4902
rch8e6c6c42015-05-01 14:05:134903 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4904 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074905 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164906
[email protected]8ddf8322012-02-23 18:08:064907 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364908 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074909 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064910 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074911 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164912
[email protected]49639fa2011-12-20 23:22:414913 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164914
bnc691fda62016-08-12 00:43:164915 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014916 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164917
4918 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014919 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164920
[email protected]58e32bb2013-01-21 18:23:254921 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164922 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254923 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4924
bnc691fda62016-08-12 00:43:164925 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524926 ASSERT_TRUE(response);
4927 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164928 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4929
4930 std::string response_data;
bnc691fda62016-08-12 00:43:164931 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164932 EXPECT_EQ("1234567890", response_data);
4933}
4934
4935// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014936TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4937 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384938
[email protected]cb9bf6ca2011-01-28 13:15:274939 HttpRequestInfo request;
4940 request.method = "GET";
bncce36dca22015-04-21 22:11:234941 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274942
[email protected]d9da5fe2010-10-13 22:37:164943 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034944 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514945 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074946 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094947 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164948
bnc691fda62016-08-12 00:43:164949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164950
bncce36dca22015-04-21 22:11:234951 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414952 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234953 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4954 // fetch https://www.example.org/ via SPDY
4955 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414956 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494957 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414958 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154959 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414960 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154961 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414962 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024963 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414964 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4965 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024966 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414967 SpdySerializedFrame window_update_get_resp(
4968 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4969 SpdySerializedFrame window_update_body(
4970 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044971
4972 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414973 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4974 CreateMockWrite(window_update_get_resp, 6),
4975 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044976 };
4977
[email protected]d9da5fe2010-10-13 22:37:164978 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414979 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094980 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414981 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4982 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134983 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164984 };
4985
rch32320842015-05-16 15:57:094986 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4987 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074988 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164989
[email protected]8ddf8322012-02-23 18:08:064990 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364991 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074992 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064993 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364994 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164996
[email protected]49639fa2011-12-20 23:22:414997 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164998
bnc691fda62016-08-12 00:43:164999 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165001
rch32320842015-05-16 15:57:095002 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555003 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095004 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595005 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165006 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015007 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165008
[email protected]58e32bb2013-01-21 18:23:255009 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165010 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255011 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5012
bnc691fda62016-08-12 00:43:165013 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525014 ASSERT_TRUE(response);
5015 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025016 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165017
5018 std::string response_data;
bnc691fda62016-08-12 00:43:165019 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235020 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165021}
5022
5023// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015024TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275025 HttpRequestInfo request;
5026 request.method = "GET";
bncce36dca22015-04-21 22:11:235027 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275028
[email protected]d9da5fe2010-10-13 22:37:165029 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035030 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515031 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075032 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165034
bnc691fda62016-08-12 00:43:165035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165036
bncce36dca22015-04-21 22:11:235037 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415038 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235039 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415040 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085041 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165042
5043 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415044 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165045 };
5046
bnc42331402016-07-25 13:36:155047 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415048 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165049 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415050 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165051 };
5052
rch8e6c6c42015-05-01 14:05:135053 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5054 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075055 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165056
[email protected]8ddf8322012-02-23 18:08:065057 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365058 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065060 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365061 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165063
[email protected]49639fa2011-12-20 23:22:415064 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165065
bnc691fda62016-08-12 00:43:165066 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165068
5069 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015070 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165071
ttuttle960fcbf2016-04-19 13:26:325072 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165073}
5074
[email protected]f6c63db52013-02-02 00:35:225075// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5076// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015077TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225078 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5079 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035080 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515081 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075082 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095083 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505084 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225085
5086 HttpRequestInfo request1;
5087 request1.method = "GET";
bncce36dca22015-04-21 22:11:235088 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225089 request1.load_flags = 0;
5090
5091 HttpRequestInfo request2;
5092 request2.method = "GET";
bncce36dca22015-04-21 22:11:235093 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225094 request2.load_flags = 0;
5095
bncce36dca22015-04-21 22:11:235096 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415097 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235098 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155099 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225100
bncce36dca22015-04-21 22:11:235101 // Fetch https://www.example.org/ via HTTP.
5102 const char get1[] =
5103 "GET / HTTP/1.1\r\n"
5104 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225105 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415106 SpdySerializedFrame wrapped_get1(
5107 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225108 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5109 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415110 SpdySerializedFrame wrapped_get_resp1(
5111 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5112 SpdySerializedFrame wrapped_body1(
5113 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5114 SpdySerializedFrame window_update(
5115 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225116
bncce36dca22015-04-21 22:11:235117 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295118 SpdyHeaderBlock connect2_block;
5119 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405120 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155121 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5122 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395123
bnc42331402016-07-25 13:36:155124 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225125
bncce36dca22015-04-21 22:11:235126 // Fetch https://mail.example.org/ via HTTP.
5127 const char get2[] =
5128 "GET / HTTP/1.1\r\n"
5129 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225130 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415131 SpdySerializedFrame wrapped_get2(
5132 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225133 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5134 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415135 SpdySerializedFrame wrapped_get_resp2(
5136 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5137 SpdySerializedFrame wrapped_body2(
5138 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225139
5140 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415141 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5142 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225143 };
5144
5145 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415146 CreateMockRead(conn_resp1, 1, ASYNC),
5147 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5148 CreateMockRead(wrapped_body1, 4, ASYNC),
5149 CreateMockRead(conn_resp2, 6, ASYNC),
5150 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5151 CreateMockRead(wrapped_body2, 9, ASYNC),
5152 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225153 };
5154
mmenke11eb5152015-06-09 14:50:505155 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5156 arraysize(spdy_writes));
5157 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225158
5159 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365160 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505161 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225162 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505163 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225164 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505165 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225166
5167 TestCompletionCallback callback;
5168
bnc691fda62016-08-12 00:43:165169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205170 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015171 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225172
5173 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165174 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225175 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5176
bnc691fda62016-08-12 00:43:165177 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525178 ASSERT_TRUE(response);
5179 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225180 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5181
5182 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295183 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165184 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505185 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225186
bnc691fda62016-08-12 00:43:165187 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205188 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015189 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225190
5191 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165192 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225193 // Even though the SPDY connection is reused, a new tunnelled connection has
5194 // to be created, so the socket's load timing looks like a fresh connection.
5195 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5196
5197 // The requests should have different IDs, since they each are using their own
5198 // separate stream.
5199 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5200
bnc691fda62016-08-12 00:43:165201 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505202 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225203}
5204
5205// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5206// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015207TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225208 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5209 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035210 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515211 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075212 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095213 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505214 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225215
5216 HttpRequestInfo request1;
5217 request1.method = "GET";
bncce36dca22015-04-21 22:11:235218 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225219 request1.load_flags = 0;
5220
5221 HttpRequestInfo request2;
5222 request2.method = "GET";
bncce36dca22015-04-21 22:11:235223 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225224 request2.load_flags = 0;
5225
bncce36dca22015-04-21 22:11:235226 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415227 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235228 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155229 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225230
bncce36dca22015-04-21 22:11:235231 // Fetch https://www.example.org/ via HTTP.
5232 const char get1[] =
5233 "GET / HTTP/1.1\r\n"
5234 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225235 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415236 SpdySerializedFrame wrapped_get1(
5237 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225238 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5239 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415240 SpdySerializedFrame wrapped_get_resp1(
5241 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5242 SpdySerializedFrame wrapped_body1(
5243 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5244 SpdySerializedFrame window_update(
5245 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225246
bncce36dca22015-04-21 22:11:235247 // Fetch https://www.example.org/2 via HTTP.
5248 const char get2[] =
5249 "GET /2 HTTP/1.1\r\n"
5250 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225251 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415252 SpdySerializedFrame wrapped_get2(
5253 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225254 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5255 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415256 SpdySerializedFrame wrapped_get_resp2(
5257 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5258 SpdySerializedFrame wrapped_body2(
5259 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225260
5261 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415262 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5263 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225264 };
5265
5266 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415267 CreateMockRead(conn_resp1, 1, ASYNC),
5268 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465269 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415270 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465271 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415272 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225273 };
5274
mmenke11eb5152015-06-09 14:50:505275 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5276 arraysize(spdy_writes));
5277 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225278
5279 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365280 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225282 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505283 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225284
5285 TestCompletionCallback callback;
5286
bnc87dcefc2017-05-25 12:47:585287 auto trans =
5288 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205289 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015290 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225291
5292 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015293 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225294
5295 LoadTimingInfo load_timing_info;
5296 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5297 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5298
5299 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525300 ASSERT_TRUE(response);
5301 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225302 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5303
5304 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295305 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505306 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225307 trans.reset();
5308
bnc87dcefc2017-05-25 12:47:585309 auto trans2 =
5310 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205311 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225313
[email protected]f6c63db52013-02-02 00:35:225314 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015315 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225316
5317 LoadTimingInfo load_timing_info2;
5318 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5319 TestLoadTimingReused(load_timing_info2);
5320
5321 // The requests should have the same ID.
5322 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5323
[email protected]90499482013-06-01 00:39:505324 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225325}
5326
5327// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5328// Proxy to different servers.
bncd16676a2016-07-20 16:23:015329TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225330 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035331 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515332 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075333 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095334 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505335 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225336
5337 HttpRequestInfo request1;
5338 request1.method = "GET";
bncce36dca22015-04-21 22:11:235339 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225340 request1.load_flags = 0;
5341
5342 HttpRequestInfo request2;
5343 request2.method = "GET";
bncce36dca22015-04-21 22:11:235344 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225345 request2.load_flags = 0;
5346
bncce36dca22015-04-21 22:11:235347 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265348 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235349 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415350 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155351 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5352 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415353 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385354 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225355
bncce36dca22015-04-21 22:11:235356 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265357 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235358 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415359 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155360 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5361 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415362 SpdySerializedFrame body2(
5363 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225364
5365 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415366 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225367 };
5368
5369 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415370 CreateMockRead(get_resp1, 1, ASYNC),
5371 CreateMockRead(body1, 2, ASYNC),
5372 CreateMockRead(get_resp2, 4, ASYNC),
5373 CreateMockRead(body2, 5, ASYNC),
5374 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225375 };
5376
mmenke11eb5152015-06-09 14:50:505377 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5378 arraysize(spdy_writes));
5379 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225380
5381 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365382 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225384
5385 TestCompletionCallback callback;
5386
bnc87dcefc2017-05-25 12:47:585387 auto trans =
5388 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205389 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015390 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225391
5392 LoadTimingInfo load_timing_info;
5393 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5394 TestLoadTimingNotReused(load_timing_info,
5395 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5396
5397 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525398 ASSERT_TRUE(response);
5399 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025400 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225401
5402 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295403 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505404 rv = trans->Read(buf.get(), 256, callback.callback());
5405 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225406 // Delete the first request, so the second one can reuse the socket.
5407 trans.reset();
5408
bnc691fda62016-08-12 00:43:165409 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205410 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015411 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225412
5413 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165414 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225415 TestLoadTimingReused(load_timing_info2);
5416
5417 // The requests should have the same ID.
5418 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5419
bnc691fda62016-08-12 00:43:165420 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505421 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225422}
5423
[email protected]2df19bb2010-08-25 20:13:465424// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015425TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465426 HttpRequestInfo request;
5427 request.method = "GET";
bncce36dca22015-04-21 22:11:235428 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465429 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295430 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465431
[email protected]79cb5c12011-09-12 13:12:045432 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035433 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515434 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075435 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275437
[email protected]2df19bb2010-08-25 20:13:465438 // Since we have proxy, should use full url
5439 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165440 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5441 "Host: www.example.org\r\n"
5442 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465443
bnc691fda62016-08-12 00:43:165444 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235445 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165446 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5447 "Host: www.example.org\r\n"
5448 "Proxy-Connection: keep-alive\r\n"
5449 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465450 };
5451
5452 // The proxy responds to the GET with a 407, using a persistent
5453 // connection.
5454 MockRead data_reads1[] = {
5455 // No credentials.
5456 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5457 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5458 MockRead("Proxy-Connection: keep-alive\r\n"),
5459 MockRead("Content-Length: 0\r\n\r\n"),
5460
5461 MockRead("HTTP/1.1 200 OK\r\n"),
5462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5463 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065464 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465465 };
5466
5467 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5468 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075469 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065470 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465472
[email protected]49639fa2011-12-20 23:22:415473 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465474
bnc691fda62016-08-12 00:43:165475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505476
bnc691fda62016-08-12 00:43:165477 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465479
5480 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015481 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465482
[email protected]58e32bb2013-01-21 18:23:255483 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165484 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255485 TestLoadTimingNotReused(load_timing_info,
5486 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5487
bnc691fda62016-08-12 00:43:165488 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525489 ASSERT_TRUE(response);
5490 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465491 EXPECT_EQ(407, response->headers->response_code());
5492 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435493 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465494
[email protected]49639fa2011-12-20 23:22:415495 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465496
bnc691fda62016-08-12 00:43:165497 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465499
5500 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015501 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465502
[email protected]58e32bb2013-01-21 18:23:255503 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165504 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255505 // Retrying with HTTP AUTH is considered to be reusing a socket.
5506 TestLoadTimingReused(load_timing_info);
5507
bnc691fda62016-08-12 00:43:165508 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525509 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465510
5511 EXPECT_TRUE(response->headers->IsKeepAlive());
5512 EXPECT_EQ(200, response->headers->response_code());
5513 EXPECT_EQ(100, response->headers->GetContentLength());
5514 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5515
5516 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525517 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465518}
5519
[email protected]23e482282013-06-14 16:08:025520void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085521 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425522 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085523 request.method = "GET";
bncce36dca22015-04-21 22:11:235524 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085525
[email protected]cb9bf6ca2011-01-28 13:15:275526 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035527 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095528 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275529
[email protected]c744cf22009-02-27 07:28:085530 // Since we have proxy, should try to establish tunnel.
5531 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175532 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5533 "Host: www.example.org:443\r\n"
5534 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085535 };
5536
5537 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235538 status, MockRead("Content-Length: 10\r\n\r\n"),
5539 // No response body because the test stops reading here.
5540 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085541 };
5542
[email protected]31a2bfe2010-02-09 08:03:395543 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5544 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075545 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085546
[email protected]49639fa2011-12-20 23:22:415547 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085548
bnc691fda62016-08-12 00:43:165549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505550
tfarina42834112016-09-22 13:38:205551 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085553
5554 rv = callback.WaitForResult();
5555 EXPECT_EQ(expected_status, rv);
5556}
5557
[email protected]23e482282013-06-14 16:08:025558void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235559 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085560 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425561 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085562}
5563
bncd16676a2016-07-20 16:23:015564TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085565 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5566}
5567
bncd16676a2016-07-20 16:23:015568TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085569 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5570}
5571
bncd16676a2016-07-20 16:23:015572TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085573 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5574}
5575
bncd16676a2016-07-20 16:23:015576TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085577 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5578}
5579
bncd16676a2016-07-20 16:23:015580TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085581 ConnectStatusHelper(
5582 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5583}
5584
bncd16676a2016-07-20 16:23:015585TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085586 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5587}
5588
bncd16676a2016-07-20 16:23:015589TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085590 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5591}
5592
bncd16676a2016-07-20 16:23:015593TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085594 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5595}
5596
bncd16676a2016-07-20 16:23:015597TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085598 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5599}
5600
bncd16676a2016-07-20 16:23:015601TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085602 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5603}
5604
bncd16676a2016-07-20 16:23:015605TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085606 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5607}
5608
bncd16676a2016-07-20 16:23:015609TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085610 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5611}
5612
bncd16676a2016-07-20 16:23:015613TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085614 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5615}
5616
bncd16676a2016-07-20 16:23:015617TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085618 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5619}
5620
bncd16676a2016-07-20 16:23:015621TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085622 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5623}
5624
bncd16676a2016-07-20 16:23:015625TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085626 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5627}
5628
bncd16676a2016-07-20 16:23:015629TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375630 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5631}
5632
bncd16676a2016-07-20 16:23:015633TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085634 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5635}
5636
bncd16676a2016-07-20 16:23:015637TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085638 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5639}
5640
bncd16676a2016-07-20 16:23:015641TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085642 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5643}
5644
bncd16676a2016-07-20 16:23:015645TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085646 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5647}
5648
bncd16676a2016-07-20 16:23:015649TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085650 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5651}
5652
bncd16676a2016-07-20 16:23:015653TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085654 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5655}
5656
bncd16676a2016-07-20 16:23:015657TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085658 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5659}
5660
bncd16676a2016-07-20 16:23:015661TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085662 ConnectStatusHelperWithExpectedStatus(
5663 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545664 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085665}
5666
bncd16676a2016-07-20 16:23:015667TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085668 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5669}
5670
bncd16676a2016-07-20 16:23:015671TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085672 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5673}
5674
bncd16676a2016-07-20 16:23:015675TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085676 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5677}
5678
bncd16676a2016-07-20 16:23:015679TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085680 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5681}
5682
bncd16676a2016-07-20 16:23:015683TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085684 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5685}
5686
bncd16676a2016-07-20 16:23:015687TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085688 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5689}
5690
bncd16676a2016-07-20 16:23:015691TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085692 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5693}
5694
bncd16676a2016-07-20 16:23:015695TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085696 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5697}
5698
bncd16676a2016-07-20 16:23:015699TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085700 ConnectStatusHelper(
5701 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5702}
5703
bncd16676a2016-07-20 16:23:015704TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085705 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5706}
5707
bncd16676a2016-07-20 16:23:015708TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085709 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5710}
5711
bncd16676a2016-07-20 16:23:015712TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085713 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5714}
5715
bncd16676a2016-07-20 16:23:015716TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085717 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5718}
5719
bncd16676a2016-07-20 16:23:015720TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085721 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5722}
5723
bncd16676a2016-07-20 16:23:015724TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085725 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5726}
5727
bncd16676a2016-07-20 16:23:015728TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085729 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5730}
5731
[email protected]038e9a32008-10-08 22:40:165732// Test the flow when both the proxy server AND origin server require
5733// authentication. Again, this uses basic auth for both since that is
5734// the simplest to mock.
bncd16676a2016-07-20 16:23:015735TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275736 HttpRequestInfo request;
5737 request.method = "GET";
bncce36dca22015-04-21 22:11:235738 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275739
[email protected]038e9a32008-10-08 22:40:165740 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035741 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075743
bnc691fda62016-08-12 00:43:165744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165745
[email protected]f9ee6b52008-11-08 06:46:235746 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235747 MockWrite(
5748 "GET http://www.example.org/ HTTP/1.1\r\n"
5749 "Host: www.example.org\r\n"
5750 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235751 };
5752
[email protected]038e9a32008-10-08 22:40:165753 MockRead data_reads1[] = {
5754 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5755 // Give a couple authenticate options (only the middle one is actually
5756 // supported).
[email protected]22927ad2009-09-21 19:56:195757 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165758 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5759 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5760 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5761 // Large content-length -- won't matter, as connection will be reset.
5762 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065763 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165764 };
5765
bnc691fda62016-08-12 00:43:165766 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165767 // request we should be issuing -- the final header line contains the
5768 // proxy's credentials.
5769 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235770 MockWrite(
5771 "GET http://www.example.org/ HTTP/1.1\r\n"
5772 "Host: www.example.org\r\n"
5773 "Proxy-Connection: keep-alive\r\n"
5774 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165775 };
5776
5777 // Now the proxy server lets the request pass through to origin server.
5778 // The origin server responds with a 401.
5779 MockRead data_reads2[] = {
5780 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5781 // Note: We are using the same realm-name as the proxy server. This is
5782 // completely valid, as realms are unique across hosts.
5783 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5784 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5785 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065786 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165787 };
5788
bnc691fda62016-08-12 00:43:165789 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165790 // the credentials for both the proxy and origin server.
5791 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235792 MockWrite(
5793 "GET http://www.example.org/ HTTP/1.1\r\n"
5794 "Host: www.example.org\r\n"
5795 "Proxy-Connection: keep-alive\r\n"
5796 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5797 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165798 };
5799
5800 // Lastly we get the desired content.
5801 MockRead data_reads3[] = {
5802 MockRead("HTTP/1.0 200 OK\r\n"),
5803 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5804 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065805 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165806 };
5807
[email protected]31a2bfe2010-02-09 08:03:395808 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5809 data_writes1, arraysize(data_writes1));
5810 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5811 data_writes2, arraysize(data_writes2));
5812 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5813 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075814 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5815 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5816 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165817
[email protected]49639fa2011-12-20 23:22:415818 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165819
tfarina42834112016-09-22 13:38:205820 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165822
5823 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015824 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165825
bnc691fda62016-08-12 00:43:165826 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525827 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045828 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165829
[email protected]49639fa2011-12-20 23:22:415830 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165831
bnc691fda62016-08-12 00:43:165832 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165834
5835 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015836 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165837
bnc691fda62016-08-12 00:43:165838 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525839 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045840 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165841
[email protected]49639fa2011-12-20 23:22:415842 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165843
bnc691fda62016-08-12 00:43:165844 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5845 callback3.callback());
robpercival214763f2016-07-01 23:27:015846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165847
5848 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015849 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165850
bnc691fda62016-08-12 00:43:165851 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525852 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165853 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165854}
[email protected]4ddaf2502008-10-23 18:26:195855
[email protected]ea9dc9a2009-09-05 00:43:325856// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5857// can't hook into its internals to cause it to generate predictable NTLM
5858// authorization headers.
5859#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295860// The NTLM authentication unit tests were generated by capturing the HTTP
5861// requests and responses using Fiddler 2 and inspecting the generated random
5862// bytes in the debugger.
5863
5864// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015865TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425866 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245867 request.method = "GET";
5868 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545869
5870 // Ensure load is not disrupted by flags which suppress behaviour specific
5871 // to other auth schemes.
5872 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245873
[email protected]cb9bf6ca2011-01-28 13:15:275874 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5875 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275877
[email protected]3f918782009-02-28 01:29:245878 MockWrite data_writes1[] = {
5879 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5880 "Host: 172.22.68.17\r\n"
5881 "Connection: keep-alive\r\n\r\n"),
5882 };
5883
5884 MockRead data_reads1[] = {
5885 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045886 // Negotiate and NTLM are often requested together. However, we only want
5887 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5888 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245889 MockRead("WWW-Authenticate: NTLM\r\n"),
5890 MockRead("Connection: close\r\n"),
5891 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365892 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245893 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065894 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245895 };
5896
5897 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165898 // After restarting with a null identity, this is the
5899 // request we should be issuing -- the final header line contains a Type
5900 // 1 message.
5901 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5902 "Host: 172.22.68.17\r\n"
5903 "Connection: keep-alive\r\n"
5904 "Authorization: NTLM "
5905 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245906
bnc691fda62016-08-12 00:43:165907 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5908 // (the credentials for the origin server). The second request continues
5909 // on the same connection.
5910 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5911 "Host: 172.22.68.17\r\n"
5912 "Connection: keep-alive\r\n"
5913 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5914 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5915 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5916 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5917 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245918 };
5919
5920 MockRead data_reads2[] = {
5921 // The origin server responds with a Type 2 message.
5922 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5923 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295924 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245925 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5926 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5927 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5928 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5929 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5930 "BtAAAAAAA=\r\n"),
5931 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365932 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245933 MockRead("You are not authorized to view this page\r\n"),
5934
5935 // Lastly we get the desired content.
5936 MockRead("HTTP/1.1 200 OK\r\n"),
5937 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5938 MockRead("Content-Length: 13\r\n\r\n"),
5939 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065940 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245941 };
5942
[email protected]31a2bfe2010-02-09 08:03:395943 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5944 data_writes1, arraysize(data_writes1));
5945 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5946 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075947 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5948 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245949
[email protected]49639fa2011-12-20 23:22:415950 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245951
bnc691fda62016-08-12 00:43:165952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505953
tfarina42834112016-09-22 13:38:205954 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245956
5957 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015958 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245959
bnc691fda62016-08-12 00:43:165960 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225961
bnc691fda62016-08-12 00:43:165962 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525963 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045964 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245965
[email protected]49639fa2011-12-20 23:22:415966 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255967
bnc691fda62016-08-12 00:43:165968 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5969 callback2.callback());
robpercival214763f2016-07-01 23:27:015970 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255971
5972 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015973 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255974
bnc691fda62016-08-12 00:43:165975 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255976
bnc691fda62016-08-12 00:43:165977 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525978 ASSERT_TRUE(response);
5979 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255980
[email protected]49639fa2011-12-20 23:22:415981 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245982
bnc691fda62016-08-12 00:43:165983 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015984 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245985
[email protected]0757e7702009-03-27 04:00:225986 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015987 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245988
bnc691fda62016-08-12 00:43:165989 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525990 ASSERT_TRUE(response);
5991 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245992 EXPECT_EQ(13, response->headers->GetContentLength());
5993}
5994
[email protected]385a4672009-03-11 22:21:295995// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015996TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425997 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295998 request.method = "GET";
5999 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296000
[email protected]cb9bf6ca2011-01-28 13:15:276001 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
6002 MockGetHostName);
danakj1fd259a02016-04-16 03:17:096003 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276004
[email protected]385a4672009-03-11 22:21:296005 MockWrite data_writes1[] = {
6006 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6007 "Host: 172.22.68.17\r\n"
6008 "Connection: keep-alive\r\n\r\n"),
6009 };
6010
6011 MockRead data_reads1[] = {
6012 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046013 // Negotiate and NTLM are often requested together. However, we only want
6014 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6015 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296016 MockRead("WWW-Authenticate: NTLM\r\n"),
6017 MockRead("Connection: close\r\n"),
6018 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366019 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296020 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066021 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296022 };
6023
6024 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166025 // After restarting with a null identity, this is the
6026 // request we should be issuing -- the final header line contains a Type
6027 // 1 message.
6028 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6029 "Host: 172.22.68.17\r\n"
6030 "Connection: keep-alive\r\n"
6031 "Authorization: NTLM "
6032 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296033
bnc691fda62016-08-12 00:43:166034 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6035 // (the credentials for the origin server). The second request continues
6036 // on the same connection.
6037 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6038 "Host: 172.22.68.17\r\n"
6039 "Connection: keep-alive\r\n"
6040 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6041 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6042 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6043 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6044 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296045 };
6046
6047 MockRead data_reads2[] = {
6048 // The origin server responds with a Type 2 message.
6049 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6050 MockRead("WWW-Authenticate: NTLM "
6051 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6052 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6053 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6054 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6055 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6056 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6057 "BtAAAAAAA=\r\n"),
6058 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366059 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296060 MockRead("You are not authorized to view this page\r\n"),
6061
6062 // Wrong password.
6063 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296064 MockRead("WWW-Authenticate: NTLM\r\n"),
6065 MockRead("Connection: close\r\n"),
6066 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366067 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296068 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066069 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296070 };
6071
6072 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166073 // After restarting with a null identity, this is the
6074 // request we should be issuing -- the final header line contains a Type
6075 // 1 message.
6076 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6077 "Host: 172.22.68.17\r\n"
6078 "Connection: keep-alive\r\n"
6079 "Authorization: NTLM "
6080 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296081
bnc691fda62016-08-12 00:43:166082 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6083 // (the credentials for the origin server). The second request continues
6084 // on the same connection.
6085 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6086 "Host: 172.22.68.17\r\n"
6087 "Connection: keep-alive\r\n"
6088 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6089 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6090 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6091 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6092 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296093 };
6094
6095 MockRead data_reads3[] = {
6096 // The origin server responds with a Type 2 message.
6097 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6098 MockRead("WWW-Authenticate: NTLM "
6099 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6100 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6101 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6102 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6103 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6104 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6105 "BtAAAAAAA=\r\n"),
6106 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366107 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296108 MockRead("You are not authorized to view this page\r\n"),
6109
6110 // Lastly we get the desired content.
6111 MockRead("HTTP/1.1 200 OK\r\n"),
6112 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6113 MockRead("Content-Length: 13\r\n\r\n"),
6114 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066115 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296116 };
6117
[email protected]31a2bfe2010-02-09 08:03:396118 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6119 data_writes1, arraysize(data_writes1));
6120 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6121 data_writes2, arraysize(data_writes2));
6122 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6123 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076124 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6125 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6126 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296127
[email protected]49639fa2011-12-20 23:22:416128 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296129
bnc691fda62016-08-12 00:43:166130 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506131
tfarina42834112016-09-22 13:38:206132 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016133 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296134
6135 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016136 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296137
bnc691fda62016-08-12 00:43:166138 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296139
bnc691fda62016-08-12 00:43:166140 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526141 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046142 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296143
[email protected]49639fa2011-12-20 23:22:416144 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296145
[email protected]0757e7702009-03-27 04:00:226146 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166147 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6148 callback2.callback());
robpercival214763f2016-07-01 23:27:016149 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296150
[email protected]10af5fe72011-01-31 16:17:256151 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016152 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296153
bnc691fda62016-08-12 00:43:166154 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416155 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166156 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016157 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256158 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016159 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166160 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226161
bnc691fda62016-08-12 00:43:166162 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526163 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046164 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226165
[email protected]49639fa2011-12-20 23:22:416166 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226167
6168 // Now enter the right password.
bnc691fda62016-08-12 00:43:166169 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6170 callback4.callback());
robpercival214763f2016-07-01 23:27:016171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256172
6173 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016174 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256175
bnc691fda62016-08-12 00:43:166176 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256177
[email protected]49639fa2011-12-20 23:22:416178 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256179
6180 // One more roundtrip
bnc691fda62016-08-12 00:43:166181 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016182 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226183
6184 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016185 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226186
bnc691fda62016-08-12 00:43:166187 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526188 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296189 EXPECT_EQ(13, response->headers->GetContentLength());
6190}
[email protected]ea9dc9a2009-09-05 00:43:326191#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296192
[email protected]4ddaf2502008-10-23 18:26:196193// Test reading a server response which has only headers, and no body.
6194// After some maximum number of bytes is consumed, the transaction should
6195// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016196TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426197 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196198 request.method = "GET";
bncce36dca22015-04-21 22:11:236199 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196200
danakj1fd259a02016-04-16 03:17:096201 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276203
[email protected]b75b7b2f2009-10-06 00:54:536204 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436205 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536206 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196207
6208 MockRead data_reads[] = {
6209 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066210 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196211 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066212 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196213 };
[email protected]31a2bfe2010-02-09 08:03:396214 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076215 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196216
[email protected]49639fa2011-12-20 23:22:416217 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196218
tfarina42834112016-09-22 13:38:206219 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016220 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196221
6222 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016223 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196224}
[email protected]f4e426b2008-11-05 00:24:496225
6226// Make sure that we don't try to reuse a TCPClientSocket when failing to
6227// establish tunnel.
6228// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016229TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276230 HttpRequestInfo request;
6231 request.method = "GET";
bncce36dca22015-04-21 22:11:236232 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276233
[email protected]f4e426b2008-11-05 00:24:496234 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036235 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016236
danakj1fd259a02016-04-16 03:17:096237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496238
bnc87dcefc2017-05-25 12:47:586239 auto trans =
6240 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496241
[email protected]f4e426b2008-11-05 00:24:496242 // Since we have proxy, should try to establish tunnel.
6243 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176244 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6245 "Host: www.example.org:443\r\n"
6246 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496247 };
6248
[email protected]77848d12008-11-14 00:00:226249 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496250 // connection. Usually a proxy would return 501 (not implemented),
6251 // or 200 (tunnel established).
6252 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236253 MockRead("HTTP/1.1 404 Not Found\r\n"),
6254 MockRead("Content-Length: 10\r\n\r\n"),
6255 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496256 };
6257
[email protected]31a2bfe2010-02-09 08:03:396258 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6259 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076260 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496261
[email protected]49639fa2011-12-20 23:22:416262 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496263
tfarina42834112016-09-22 13:38:206264 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016265 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496266
6267 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016268 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496269
[email protected]b4404c02009-04-10 16:38:526270 // Empty the current queue. This is necessary because idle sockets are
6271 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556272 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526273
[email protected]f4e426b2008-11-05 00:24:496274 // We now check to make sure the TCPClientSocket was not added back to
6275 // the pool.
[email protected]90499482013-06-01 00:39:506276 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496277 trans.reset();
fdoray92e35a72016-06-10 15:54:556278 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496279 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506280 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496281}
[email protected]372d34a2008-11-05 21:30:516282
[email protected]1b157c02009-04-21 01:55:406283// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016284TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426285 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406286 request.method = "GET";
bncce36dca22015-04-21 22:11:236287 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406288
danakj1fd259a02016-04-16 03:17:096289 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276290
bnc691fda62016-08-12 00:43:166291 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276292
[email protected]1b157c02009-04-21 01:55:406293 MockRead data_reads[] = {
6294 // A part of the response body is received with the response headers.
6295 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6296 // The rest of the response body is received in two parts.
6297 MockRead("lo"),
6298 MockRead(" world"),
6299 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066300 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406301 };
6302
[email protected]31a2bfe2010-02-09 08:03:396303 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076304 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406305
[email protected]49639fa2011-12-20 23:22:416306 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406307
tfarina42834112016-09-22 13:38:206308 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016309 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406310
6311 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016312 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406313
bnc691fda62016-08-12 00:43:166314 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526315 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406316
wezca1070932016-05-26 20:30:526317 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406318 std::string status_line = response->headers->GetStatusLine();
6319 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6320
[email protected]90499482013-06-01 00:39:506321 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406322
6323 std::string response_data;
bnc691fda62016-08-12 00:43:166324 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016325 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406326 EXPECT_EQ("hello world", response_data);
6327
6328 // Empty the current queue. This is necessary because idle sockets are
6329 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556330 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406331
6332 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506333 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406334}
6335
[email protected]76a505b2010-08-25 06:23:006336// Make sure that we recycle a SSL socket after reading all of the response
6337// body.
bncd16676a2016-07-20 16:23:016338TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006339 HttpRequestInfo request;
6340 request.method = "GET";
bncce36dca22015-04-21 22:11:236341 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006342
6343 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236344 MockWrite(
6345 "GET / HTTP/1.1\r\n"
6346 "Host: www.example.org\r\n"
6347 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006348 };
6349
6350 MockRead data_reads[] = {
6351 MockRead("HTTP/1.1 200 OK\r\n"),
6352 MockRead("Content-Length: 11\r\n\r\n"),
6353 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066354 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006355 };
6356
[email protected]8ddf8322012-02-23 18:08:066357 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006359
6360 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6361 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076362 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006363
[email protected]49639fa2011-12-20 23:22:416364 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006365
danakj1fd259a02016-04-16 03:17:096366 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166367 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006368
tfarina42834112016-09-22 13:38:206369 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006370
robpercival214763f2016-07-01 23:27:016371 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6372 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006373
bnc691fda62016-08-12 00:43:166374 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526375 ASSERT_TRUE(response);
6376 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006377 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6378
[email protected]90499482013-06-01 00:39:506379 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006380
6381 std::string response_data;
bnc691fda62016-08-12 00:43:166382 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016383 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006384 EXPECT_EQ("hello world", response_data);
6385
6386 // Empty the current queue. This is necessary because idle sockets are
6387 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556388 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006389
6390 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506391 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006392}
6393
6394// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6395// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016396TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006397 HttpRequestInfo request;
6398 request.method = "GET";
bncce36dca22015-04-21 22:11:236399 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006400
6401 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236402 MockWrite(
6403 "GET / HTTP/1.1\r\n"
6404 "Host: www.example.org\r\n"
6405 "Connection: keep-alive\r\n\r\n"),
6406 MockWrite(
6407 "GET / HTTP/1.1\r\n"
6408 "Host: www.example.org\r\n"
6409 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006410 };
6411
6412 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426413 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6414 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006415
[email protected]8ddf8322012-02-23 18:08:066416 SSLSocketDataProvider ssl(ASYNC, OK);
6417 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6419 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006420
6421 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6422 data_writes, arraysize(data_writes));
6423 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6424 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076425 session_deps_.socket_factory->AddSocketDataProvider(&data);
6426 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006427
[email protected]49639fa2011-12-20 23:22:416428 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006429
danakj1fd259a02016-04-16 03:17:096430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586431 auto trans =
6432 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006433
tfarina42834112016-09-22 13:38:206434 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006435
robpercival214763f2016-07-01 23:27:016436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6437 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006438
6439 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526440 ASSERT_TRUE(response);
6441 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006442 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6443
[email protected]90499482013-06-01 00:39:506444 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006445
6446 std::string response_data;
6447 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016448 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006449 EXPECT_EQ("hello world", response_data);
6450
6451 // Empty the current queue. This is necessary because idle sockets are
6452 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556453 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006454
6455 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506456 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006457
6458 // Now start the second transaction, which should reuse the previous socket.
6459
bnc87dcefc2017-05-25 12:47:586460 trans =
6461 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006462
tfarina42834112016-09-22 13:38:206463 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006464
robpercival214763f2016-07-01 23:27:016465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6466 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006467
6468 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526469 ASSERT_TRUE(response);
6470 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006471 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6472
[email protected]90499482013-06-01 00:39:506473 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006474
6475 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016476 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006477 EXPECT_EQ("hello world", response_data);
6478
6479 // Empty the current queue. This is necessary because idle sockets are
6480 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556481 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006482
6483 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506484 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006485}
6486
maksim.sisov0adf8592016-07-15 06:25:566487// Grab a socket, use it, and put it back into the pool. Then, make
6488// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016489TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566490 HttpRequestInfo request;
6491 request.method = "GET";
6492 request.url = GURL("http://www.example.org/");
6493 request.load_flags = 0;
6494
6495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6496
bnc691fda62016-08-12 00:43:166497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566498
6499 MockRead data_reads[] = {
6500 // A part of the response body is received with the response headers.
6501 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6502 // The rest of the response body is received in two parts.
6503 MockRead("lo"), MockRead(" world"),
6504 MockRead("junk"), // Should not be read!!
6505 MockRead(SYNCHRONOUS, OK),
6506 };
6507
6508 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6509 session_deps_.socket_factory->AddSocketDataProvider(&data);
6510
6511 TestCompletionCallback callback;
6512
tfarina42834112016-09-22 13:38:206513 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566514 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6515
6516 EXPECT_THAT(callback.GetResult(rv), IsOk());
6517
bnc691fda62016-08-12 00:43:166518 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566519 ASSERT_TRUE(response);
6520 EXPECT_TRUE(response->headers);
6521 std::string status_line = response->headers->GetStatusLine();
6522 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6523
6524 // Make memory critical notification and ensure the transaction still has been
6525 // operating right.
6526 base::MemoryPressureListener::NotifyMemoryPressure(
6527 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6528 base::RunLoop().RunUntilIdle();
6529
6530 // Socket should not be flushed as long as it is not idle.
6531 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6532
6533 std::string response_data;
bnc691fda62016-08-12 00:43:166534 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566535 EXPECT_THAT(rv, IsOk());
6536 EXPECT_EQ("hello world", response_data);
6537
6538 // Empty the current queue. This is necessary because idle sockets are
6539 // added to the connection pool asynchronously with a PostTask.
6540 base::RunLoop().RunUntilIdle();
6541
6542 // We now check to make sure the socket was added back to the pool.
6543 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6544
6545 // Idle sockets should be flushed now.
6546 base::MemoryPressureListener::NotifyMemoryPressure(
6547 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6548 base::RunLoop().RunUntilIdle();
6549
6550 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6551}
6552
6553// Grab an SSL socket, use it, and put it back into the pool. Then, make
6554// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016555TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566556 HttpRequestInfo request;
6557 request.method = "GET";
6558 request.url = GURL("https://www.example.org/");
6559 request.load_flags = 0;
6560
6561 MockWrite data_writes[] = {
6562 MockWrite("GET / HTTP/1.1\r\n"
6563 "Host: www.example.org\r\n"
6564 "Connection: keep-alive\r\n\r\n"),
6565 };
6566
6567 MockRead data_reads[] = {
6568 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6569 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6570
6571 SSLSocketDataProvider ssl(ASYNC, OK);
6572 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6573
6574 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6575 arraysize(data_writes));
6576 session_deps_.socket_factory->AddSocketDataProvider(&data);
6577
6578 TestCompletionCallback callback;
6579
6580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566582
6583 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206584 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566585
6586 EXPECT_THAT(callback.GetResult(rv), IsOk());
6587
bnc691fda62016-08-12 00:43:166588 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566589 ASSERT_TRUE(response);
6590 ASSERT_TRUE(response->headers);
6591 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6592
6593 // Make memory critical notification and ensure the transaction still has been
6594 // operating right.
6595 base::MemoryPressureListener::NotifyMemoryPressure(
6596 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6597 base::RunLoop().RunUntilIdle();
6598
6599 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6600
6601 std::string response_data;
bnc691fda62016-08-12 00:43:166602 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566603 EXPECT_THAT(rv, IsOk());
6604 EXPECT_EQ("hello world", response_data);
6605
6606 // Empty the current queue. This is necessary because idle sockets are
6607 // added to the connection pool asynchronously with a PostTask.
6608 base::RunLoop().RunUntilIdle();
6609
6610 // We now check to make sure the socket was added back to the pool.
6611 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6612
6613 // Make memory notification once again and ensure idle socket is closed.
6614 base::MemoryPressureListener::NotifyMemoryPressure(
6615 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6616 base::RunLoop().RunUntilIdle();
6617
6618 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6619}
6620
[email protected]b4404c02009-04-10 16:38:526621// Make sure that we recycle a socket after a zero-length response.
6622// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016623TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426624 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526625 request.method = "GET";
bncce36dca22015-04-21 22:11:236626 request.url = GURL(
6627 "http://www.example.org/csi?v=3&s=web&action=&"
6628 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6629 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6630 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526631
danakj1fd259a02016-04-16 03:17:096632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276633
[email protected]b4404c02009-04-10 16:38:526634 MockRead data_reads[] = {
6635 MockRead("HTTP/1.1 204 No Content\r\n"
6636 "Content-Length: 0\r\n"
6637 "Content-Type: text/html\r\n\r\n"),
6638 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066639 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526640 };
6641
[email protected]31a2bfe2010-02-09 08:03:396642 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076643 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526644
mmenkecc2298e2015-12-07 18:20:186645 // Transaction must be created after the MockReads, so it's destroyed before
6646 // them.
bnc691fda62016-08-12 00:43:166647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186648
[email protected]49639fa2011-12-20 23:22:416649 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526650
tfarina42834112016-09-22 13:38:206651 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526653
6654 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016655 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526656
bnc691fda62016-08-12 00:43:166657 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526658 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526659
wezca1070932016-05-26 20:30:526660 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526661 std::string status_line = response->headers->GetStatusLine();
6662 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6663
[email protected]90499482013-06-01 00:39:506664 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526665
6666 std::string response_data;
bnc691fda62016-08-12 00:43:166667 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016668 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526669 EXPECT_EQ("", response_data);
6670
6671 // Empty the current queue. This is necessary because idle sockets are
6672 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556673 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526674
6675 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506676 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526677}
6678
bncd16676a2016-07-20 16:23:016679TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096680 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226681 element_readers.push_back(
ricea2deef682016-09-09 08:04:076682 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226683 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276684
[email protected]1c773ea12009-04-28 19:58:426685 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516686 // Transaction 1: a GET request that succeeds. The socket is recycled
6687 // after use.
6688 request[0].method = "GET";
6689 request[0].url = GURL("http://www.google.com/");
6690 request[0].load_flags = 0;
6691 // Transaction 2: a POST request. Reuses the socket kept alive from
6692 // transaction 1. The first attempts fails when writing the POST data.
6693 // This causes the transaction to retry with a new socket. The second
6694 // attempt succeeds.
6695 request[1].method = "POST";
6696 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276697 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516698 request[1].load_flags = 0;
6699
danakj1fd259a02016-04-16 03:17:096700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516701
6702 // The first socket is used for transaction 1 and the first attempt of
6703 // transaction 2.
6704
6705 // The response of transaction 1.
6706 MockRead data_reads1[] = {
6707 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6708 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066709 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516710 };
6711 // The mock write results of transaction 1 and the first attempt of
6712 // transaction 2.
6713 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066714 MockWrite(SYNCHRONOUS, 64), // GET
6715 MockWrite(SYNCHRONOUS, 93), // POST
6716 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516717 };
[email protected]31a2bfe2010-02-09 08:03:396718 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6719 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516720
6721 // The second socket is used for the second attempt of transaction 2.
6722
6723 // The response of transaction 2.
6724 MockRead data_reads2[] = {
6725 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6726 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066727 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516728 };
6729 // The mock write results of the second attempt of transaction 2.
6730 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066731 MockWrite(SYNCHRONOUS, 93), // POST
6732 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516733 };
[email protected]31a2bfe2010-02-09 08:03:396734 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6735 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516736
[email protected]bb88e1d32013-05-03 23:11:076737 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6738 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516739
thestig9d3bb0c2015-01-24 00:49:516740 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516741 "hello world", "welcome"
6742 };
6743
6744 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516746
[email protected]49639fa2011-12-20 23:22:416747 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516748
tfarina42834112016-09-22 13:38:206749 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516751
6752 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016753 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516754
bnc691fda62016-08-12 00:43:166755 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526756 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516757
wezca1070932016-05-26 20:30:526758 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516759 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6760
6761 std::string response_data;
bnc691fda62016-08-12 00:43:166762 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016763 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516764 EXPECT_EQ(kExpectedResponseData[i], response_data);
6765 }
6766}
[email protected]f9ee6b52008-11-08 06:46:236767
6768// Test the request-challenge-retry sequence for basic auth when there is
6769// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166770// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016771TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426772 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236773 request.method = "GET";
bncce36dca22015-04-21 22:11:236774 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416775 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296776
danakj1fd259a02016-04-16 03:17:096777 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166778 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276779
[email protected]a97cca42009-08-14 01:00:296780 // The password contains an escaped character -- for this test to pass it
6781 // will need to be unescaped by HttpNetworkTransaction.
6782 EXPECT_EQ("b%40r", request.url.password());
6783
[email protected]f9ee6b52008-11-08 06:46:236784 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236785 MockWrite(
6786 "GET / HTTP/1.1\r\n"
6787 "Host: www.example.org\r\n"
6788 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236789 };
6790
6791 MockRead data_reads1[] = {
6792 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6793 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6794 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066795 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236796 };
6797
[email protected]2262e3a2012-05-22 16:08:166798 // After the challenge above, the transaction will be restarted using the
6799 // identity from the url (foo, b@r) to answer the challenge.
6800 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236801 MockWrite(
6802 "GET / HTTP/1.1\r\n"
6803 "Host: www.example.org\r\n"
6804 "Connection: keep-alive\r\n"
6805 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166806 };
6807
6808 MockRead data_reads2[] = {
6809 MockRead("HTTP/1.0 200 OK\r\n"),
6810 MockRead("Content-Length: 100\r\n\r\n"),
6811 MockRead(SYNCHRONOUS, OK),
6812 };
6813
[email protected]31a2bfe2010-02-09 08:03:396814 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6815 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166816 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6817 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076818 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6819 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236820
[email protected]49639fa2011-12-20 23:22:416821 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206822 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236824 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016825 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166826 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166827
6828 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166829 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166831 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016832 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166833 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226834
bnc691fda62016-08-12 00:43:166835 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526836 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166837
6838 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526839 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166840
6841 EXPECT_EQ(100, response->headers->GetContentLength());
6842
6843 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556844 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166845}
6846
6847// Test the request-challenge-retry sequence for basic auth when there is an
6848// incorrect identity in the URL. The identity from the URL should be used only
6849// once.
bncd16676a2016-07-20 16:23:016850TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166851 HttpRequestInfo request;
6852 request.method = "GET";
6853 // Note: the URL has a username:password in it. The password "baz" is
6854 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236855 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166856
6857 request.load_flags = LOAD_NORMAL;
6858
danakj1fd259a02016-04-16 03:17:096859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166860 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166861
6862 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236863 MockWrite(
6864 "GET / HTTP/1.1\r\n"
6865 "Host: www.example.org\r\n"
6866 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166867 };
6868
6869 MockRead data_reads1[] = {
6870 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6871 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6872 MockRead("Content-Length: 10\r\n\r\n"),
6873 MockRead(SYNCHRONOUS, ERR_FAILED),
6874 };
6875
6876 // After the challenge above, the transaction will be restarted using the
6877 // identity from the url (foo, baz) to answer the challenge.
6878 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236879 MockWrite(
6880 "GET / HTTP/1.1\r\n"
6881 "Host: www.example.org\r\n"
6882 "Connection: keep-alive\r\n"
6883 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166884 };
6885
6886 MockRead data_reads2[] = {
6887 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6888 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6889 MockRead("Content-Length: 10\r\n\r\n"),
6890 MockRead(SYNCHRONOUS, ERR_FAILED),
6891 };
6892
6893 // After the challenge above, the transaction will be restarted using the
6894 // identity supplied by the user (foo, bar) to answer the challenge.
6895 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236896 MockWrite(
6897 "GET / HTTP/1.1\r\n"
6898 "Host: www.example.org\r\n"
6899 "Connection: keep-alive\r\n"
6900 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166901 };
6902
6903 MockRead data_reads3[] = {
6904 MockRead("HTTP/1.0 200 OK\r\n"),
6905 MockRead("Content-Length: 100\r\n\r\n"),
6906 MockRead(SYNCHRONOUS, OK),
6907 };
6908
6909 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6910 data_writes1, arraysize(data_writes1));
6911 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6912 data_writes2, arraysize(data_writes2));
6913 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6914 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076915 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6916 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6917 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166918
6919 TestCompletionCallback callback1;
6920
tfarina42834112016-09-22 13:38:206921 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166923
6924 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016925 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166926
bnc691fda62016-08-12 00:43:166927 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166928 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166929 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166931 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016932 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166933 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166934
bnc691fda62016-08-12 00:43:166935 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526936 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166937 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6938
6939 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166940 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166942 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016943 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166944 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166945
bnc691fda62016-08-12 00:43:166946 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526947 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166948
6949 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526950 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166951
6952 EXPECT_EQ(100, response->headers->GetContentLength());
6953
[email protected]ea9dc9a2009-09-05 00:43:326954 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556955 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326956}
6957
[email protected]2217aa22013-10-11 03:03:546958
6959// Test the request-challenge-retry sequence for basic auth when there is a
6960// correct identity in the URL, but its use is being suppressed. The identity
6961// from the URL should never be used.
bncd16676a2016-07-20 16:23:016962TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546963 HttpRequestInfo request;
6964 request.method = "GET";
bncce36dca22015-04-21 22:11:236965 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546966 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6967
danakj1fd259a02016-04-16 03:17:096968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546970
6971 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236972 MockWrite(
6973 "GET / HTTP/1.1\r\n"
6974 "Host: www.example.org\r\n"
6975 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546976 };
6977
6978 MockRead data_reads1[] = {
6979 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6980 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6981 MockRead("Content-Length: 10\r\n\r\n"),
6982 MockRead(SYNCHRONOUS, ERR_FAILED),
6983 };
6984
6985 // After the challenge above, the transaction will be restarted using the
6986 // identity supplied by the user, not the one in the URL, to answer the
6987 // challenge.
6988 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236989 MockWrite(
6990 "GET / HTTP/1.1\r\n"
6991 "Host: www.example.org\r\n"
6992 "Connection: keep-alive\r\n"
6993 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546994 };
6995
6996 MockRead data_reads3[] = {
6997 MockRead("HTTP/1.0 200 OK\r\n"),
6998 MockRead("Content-Length: 100\r\n\r\n"),
6999 MockRead(SYNCHRONOUS, OK),
7000 };
7001
7002 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7003 data_writes1, arraysize(data_writes1));
7004 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7005 data_writes3, arraysize(data_writes3));
7006 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7007 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7008
7009 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207010 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017011 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547012 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017013 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167014 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547015
bnc691fda62016-08-12 00:43:167016 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527017 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547018 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7019
7020 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167021 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547023 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017024 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167025 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547026
bnc691fda62016-08-12 00:43:167027 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527028 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547029
7030 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527031 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547032 EXPECT_EQ(100, response->headers->GetContentLength());
7033
7034 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557035 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547036}
7037
[email protected]f9ee6b52008-11-08 06:46:237038// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017039TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097040 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237041
7042 // Transaction 1: authenticate (foo, bar) on MyRealm1
7043 {
[email protected]1c773ea12009-04-28 19:58:427044 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237045 request.method = "GET";
bncce36dca22015-04-21 22:11:237046 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237047
bnc691fda62016-08-12 00:43:167048 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277049
[email protected]f9ee6b52008-11-08 06:46:237050 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237051 MockWrite(
7052 "GET /x/y/z HTTP/1.1\r\n"
7053 "Host: www.example.org\r\n"
7054 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237055 };
7056
7057 MockRead data_reads1[] = {
7058 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7059 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7060 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067061 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237062 };
7063
7064 // Resend with authorization (username=foo, password=bar)
7065 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237066 MockWrite(
7067 "GET /x/y/z HTTP/1.1\r\n"
7068 "Host: www.example.org\r\n"
7069 "Connection: keep-alive\r\n"
7070 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237071 };
7072
7073 // Sever accepts the authorization.
7074 MockRead data_reads2[] = {
7075 MockRead("HTTP/1.0 200 OK\r\n"),
7076 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067077 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237078 };
7079
[email protected]31a2bfe2010-02-09 08:03:397080 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7081 data_writes1, arraysize(data_writes1));
7082 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7083 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077084 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7085 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237086
[email protected]49639fa2011-12-20 23:22:417087 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237088
tfarina42834112016-09-22 13:38:207089 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237091
7092 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017093 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237094
bnc691fda62016-08-12 00:43:167095 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527096 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047097 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237098
[email protected]49639fa2011-12-20 23:22:417099 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237100
bnc691fda62016-08-12 00:43:167101 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7102 callback2.callback());
robpercival214763f2016-07-01 23:27:017103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237104
7105 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017106 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237107
bnc691fda62016-08-12 00:43:167108 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527109 ASSERT_TRUE(response);
7110 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237111 EXPECT_EQ(100, response->headers->GetContentLength());
7112 }
7113
7114 // ------------------------------------------------------------------------
7115
7116 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7117 {
[email protected]1c773ea12009-04-28 19:58:427118 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237119 request.method = "GET";
7120 // Note that Transaction 1 was at /x/y/z, so this is in the same
7121 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237122 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237123
bnc691fda62016-08-12 00:43:167124 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277125
[email protected]f9ee6b52008-11-08 06:46:237126 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237127 MockWrite(
7128 "GET /x/y/a/b HTTP/1.1\r\n"
7129 "Host: www.example.org\r\n"
7130 "Connection: keep-alive\r\n"
7131 // Send preemptive authorization for MyRealm1
7132 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237133 };
7134
7135 // The server didn't like the preemptive authorization, and
7136 // challenges us for a different realm (MyRealm2).
7137 MockRead data_reads1[] = {
7138 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7139 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7140 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067141 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237142 };
7143
7144 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7145 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237146 MockWrite(
7147 "GET /x/y/a/b HTTP/1.1\r\n"
7148 "Host: www.example.org\r\n"
7149 "Connection: keep-alive\r\n"
7150 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237151 };
7152
7153 // Sever accepts the authorization.
7154 MockRead data_reads2[] = {
7155 MockRead("HTTP/1.0 200 OK\r\n"),
7156 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067157 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237158 };
7159
[email protected]31a2bfe2010-02-09 08:03:397160 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7161 data_writes1, arraysize(data_writes1));
7162 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7163 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077164 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7165 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237166
[email protected]49639fa2011-12-20 23:22:417167 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237168
tfarina42834112016-09-22 13:38:207169 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237171
7172 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017173 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237174
bnc691fda62016-08-12 00:43:167175 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527176 ASSERT_TRUE(response);
7177 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047178 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437179 EXPECT_EQ("http://www.example.org",
7180 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047181 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197182 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237183
[email protected]49639fa2011-12-20 23:22:417184 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237185
bnc691fda62016-08-12 00:43:167186 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7187 callback2.callback());
robpercival214763f2016-07-01 23:27:017188 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237189
7190 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017191 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237192
bnc691fda62016-08-12 00:43:167193 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527194 ASSERT_TRUE(response);
7195 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237196 EXPECT_EQ(100, response->headers->GetContentLength());
7197 }
7198
7199 // ------------------------------------------------------------------------
7200
7201 // Transaction 3: Resend a request in MyRealm's protection space --
7202 // succeed with preemptive authorization.
7203 {
[email protected]1c773ea12009-04-28 19:58:427204 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237205 request.method = "GET";
bncce36dca22015-04-21 22:11:237206 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237207
bnc691fda62016-08-12 00:43:167208 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277209
[email protected]f9ee6b52008-11-08 06:46:237210 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237211 MockWrite(
7212 "GET /x/y/z2 HTTP/1.1\r\n"
7213 "Host: www.example.org\r\n"
7214 "Connection: keep-alive\r\n"
7215 // The authorization for MyRealm1 gets sent preemptively
7216 // (since the url is in the same protection space)
7217 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237218 };
7219
7220 // Sever accepts the preemptive authorization
7221 MockRead data_reads1[] = {
7222 MockRead("HTTP/1.0 200 OK\r\n"),
7223 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067224 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237225 };
7226
[email protected]31a2bfe2010-02-09 08:03:397227 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7228 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077229 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237230
[email protected]49639fa2011-12-20 23:22:417231 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237232
tfarina42834112016-09-22 13:38:207233 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017234 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237235
7236 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017237 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237238
bnc691fda62016-08-12 00:43:167239 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527240 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237241
wezca1070932016-05-26 20:30:527242 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237243 EXPECT_EQ(100, response->headers->GetContentLength());
7244 }
7245
7246 // ------------------------------------------------------------------------
7247
7248 // Transaction 4: request another URL in MyRealm (however the
7249 // url is not known to belong to the protection space, so no pre-auth).
7250 {
[email protected]1c773ea12009-04-28 19:58:427251 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237252 request.method = "GET";
bncce36dca22015-04-21 22:11:237253 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237254
bnc691fda62016-08-12 00:43:167255 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277256
[email protected]f9ee6b52008-11-08 06:46:237257 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237258 MockWrite(
7259 "GET /x/1 HTTP/1.1\r\n"
7260 "Host: www.example.org\r\n"
7261 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237262 };
7263
7264 MockRead data_reads1[] = {
7265 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7266 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7267 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067268 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237269 };
7270
7271 // Resend with authorization from MyRealm's cache.
7272 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237273 MockWrite(
7274 "GET /x/1 HTTP/1.1\r\n"
7275 "Host: www.example.org\r\n"
7276 "Connection: keep-alive\r\n"
7277 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237278 };
7279
7280 // Sever accepts the authorization.
7281 MockRead data_reads2[] = {
7282 MockRead("HTTP/1.0 200 OK\r\n"),
7283 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067284 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237285 };
7286
[email protected]31a2bfe2010-02-09 08:03:397287 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7288 data_writes1, arraysize(data_writes1));
7289 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7290 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077291 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7292 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237293
[email protected]49639fa2011-12-20 23:22:417294 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237295
tfarina42834112016-09-22 13:38:207296 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237298
7299 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017300 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237301
bnc691fda62016-08-12 00:43:167302 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417303 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167304 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227306 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017307 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167308 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227309
bnc691fda62016-08-12 00:43:167310 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527311 ASSERT_TRUE(response);
7312 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237313 EXPECT_EQ(100, response->headers->GetContentLength());
7314 }
7315
7316 // ------------------------------------------------------------------------
7317
7318 // Transaction 5: request a URL in MyRealm, but the server rejects the
7319 // cached identity. Should invalidate and re-prompt.
7320 {
[email protected]1c773ea12009-04-28 19:58:427321 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237322 request.method = "GET";
bncce36dca22015-04-21 22:11:237323 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237324
bnc691fda62016-08-12 00:43:167325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277326
[email protected]f9ee6b52008-11-08 06:46:237327 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237328 MockWrite(
7329 "GET /p/q/t HTTP/1.1\r\n"
7330 "Host: www.example.org\r\n"
7331 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237332 };
7333
7334 MockRead data_reads1[] = {
7335 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7336 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7337 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067338 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237339 };
7340
7341 // Resend with authorization from cache for MyRealm.
7342 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237343 MockWrite(
7344 "GET /p/q/t HTTP/1.1\r\n"
7345 "Host: www.example.org\r\n"
7346 "Connection: keep-alive\r\n"
7347 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237348 };
7349
7350 // Sever rejects the authorization.
7351 MockRead data_reads2[] = {
7352 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7353 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7354 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067355 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237356 };
7357
7358 // At this point we should prompt for new credentials for MyRealm.
7359 // Restart with username=foo3, password=foo4.
7360 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237361 MockWrite(
7362 "GET /p/q/t HTTP/1.1\r\n"
7363 "Host: www.example.org\r\n"
7364 "Connection: keep-alive\r\n"
7365 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237366 };
7367
7368 // Sever accepts the authorization.
7369 MockRead data_reads3[] = {
7370 MockRead("HTTP/1.0 200 OK\r\n"),
7371 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067372 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237373 };
7374
[email protected]31a2bfe2010-02-09 08:03:397375 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7376 data_writes1, arraysize(data_writes1));
7377 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7378 data_writes2, arraysize(data_writes2));
7379 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7380 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077381 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7382 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7383 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237384
[email protected]49639fa2011-12-20 23:22:417385 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237386
tfarina42834112016-09-22 13:38:207387 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017388 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237389
7390 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017391 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237392
bnc691fda62016-08-12 00:43:167393 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417394 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167395 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227397 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017398 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167399 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227400
bnc691fda62016-08-12 00:43:167401 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527402 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047403 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237404
[email protected]49639fa2011-12-20 23:22:417405 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237406
bnc691fda62016-08-12 00:43:167407 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7408 callback3.callback());
robpercival214763f2016-07-01 23:27:017409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237410
[email protected]0757e7702009-03-27 04:00:227411 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017412 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237413
bnc691fda62016-08-12 00:43:167414 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527415 ASSERT_TRUE(response);
7416 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237417 EXPECT_EQ(100, response->headers->GetContentLength());
7418 }
7419}
[email protected]89ceba9a2009-03-21 03:46:067420
[email protected]3c32c5f2010-05-18 15:18:127421// Tests that nonce count increments when multiple auth attempts
7422// are started with the same nonce.
bncd16676a2016-07-20 16:23:017423TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447424 HttpAuthHandlerDigest::Factory* digest_factory =
7425 new HttpAuthHandlerDigest::Factory();
7426 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7427 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7428 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077429 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127431
7432 // Transaction 1: authenticate (foo, bar) on MyRealm1
7433 {
[email protected]3c32c5f2010-05-18 15:18:127434 HttpRequestInfo request;
7435 request.method = "GET";
bncce36dca22015-04-21 22:11:237436 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127437
bnc691fda62016-08-12 00:43:167438 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277439
[email protected]3c32c5f2010-05-18 15:18:127440 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237441 MockWrite(
7442 "GET /x/y/z HTTP/1.1\r\n"
7443 "Host: www.example.org\r\n"
7444 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127445 };
7446
7447 MockRead data_reads1[] = {
7448 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7449 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7450 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067451 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127452 };
7453
7454 // Resend with authorization (username=foo, password=bar)
7455 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237456 MockWrite(
7457 "GET /x/y/z HTTP/1.1\r\n"
7458 "Host: www.example.org\r\n"
7459 "Connection: keep-alive\r\n"
7460 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7461 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7462 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7463 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127464 };
7465
7466 // Sever accepts the authorization.
7467 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087468 MockRead("HTTP/1.0 200 OK\r\n"),
7469 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127470 };
7471
7472 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7473 data_writes1, arraysize(data_writes1));
7474 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7475 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077476 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7477 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127478
[email protected]49639fa2011-12-20 23:22:417479 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127480
tfarina42834112016-09-22 13:38:207481 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127483
7484 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017485 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127486
bnc691fda62016-08-12 00:43:167487 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527488 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047489 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127490
[email protected]49639fa2011-12-20 23:22:417491 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127492
bnc691fda62016-08-12 00:43:167493 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7494 callback2.callback());
robpercival214763f2016-07-01 23:27:017495 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127496
7497 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017498 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127499
bnc691fda62016-08-12 00:43:167500 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527501 ASSERT_TRUE(response);
7502 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127503 }
7504
7505 // ------------------------------------------------------------------------
7506
7507 // Transaction 2: Request another resource in digestive's protection space.
7508 // This will preemptively add an Authorization header which should have an
7509 // "nc" value of 2 (as compared to 1 in the first use.
7510 {
[email protected]3c32c5f2010-05-18 15:18:127511 HttpRequestInfo request;
7512 request.method = "GET";
7513 // Note that Transaction 1 was at /x/y/z, so this is in the same
7514 // protection space as digest.
bncce36dca22015-04-21 22:11:237515 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127516
bnc691fda62016-08-12 00:43:167517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277518
[email protected]3c32c5f2010-05-18 15:18:127519 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237520 MockWrite(
7521 "GET /x/y/a/b HTTP/1.1\r\n"
7522 "Host: www.example.org\r\n"
7523 "Connection: keep-alive\r\n"
7524 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7525 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7526 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7527 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127528 };
7529
7530 // Sever accepts the authorization.
7531 MockRead data_reads1[] = {
7532 MockRead("HTTP/1.0 200 OK\r\n"),
7533 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067534 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127535 };
7536
7537 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7538 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077539 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127540
[email protected]49639fa2011-12-20 23:22:417541 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127542
tfarina42834112016-09-22 13:38:207543 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127545
7546 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017547 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127548
bnc691fda62016-08-12 00:43:167549 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527550 ASSERT_TRUE(response);
7551 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127552 }
7553}
7554
[email protected]89ceba9a2009-03-21 03:46:067555// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017556TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067557 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097558 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067560
7561 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167562 trans.read_buf_ = new IOBuffer(15);
7563 trans.read_buf_len_ = 15;
7564 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067565
7566 // Setup state in response_
bnc691fda62016-08-12 00:43:167567 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577568 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087569 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577570 response->response_time = base::Time::Now();
7571 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067572
7573 { // Setup state for response_.vary_data
7574 HttpRequestInfo request;
7575 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7576 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277577 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437578 request.extra_headers.SetHeader("Foo", "1");
7579 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507580 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067581 }
7582
7583 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167584 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067585
7586 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167587 EXPECT_FALSE(trans.read_buf_);
7588 EXPECT_EQ(0, trans.read_buf_len_);
7589 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527590 EXPECT_FALSE(response->auth_challenge);
7591 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047592 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087593 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577594 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067595}
7596
[email protected]bacff652009-03-31 17:50:337597// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017598TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337599 HttpRequestInfo request;
7600 request.method = "GET";
bncce36dca22015-04-21 22:11:237601 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337602
danakj1fd259a02016-04-16 03:17:097603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277605
[email protected]bacff652009-03-31 17:50:337606 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237607 MockWrite(
7608 "GET / HTTP/1.1\r\n"
7609 "Host: www.example.org\r\n"
7610 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337611 };
7612
7613 MockRead data_reads[] = {
7614 MockRead("HTTP/1.0 200 OK\r\n"),
7615 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7616 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067617 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337618 };
7619
[email protected]5ecc992a42009-11-11 01:41:597620 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397621 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7622 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067623 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7624 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337625
[email protected]bb88e1d32013-05-03 23:11:077626 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7627 session_deps_.socket_factory->AddSocketDataProvider(&data);
7628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337630
[email protected]49639fa2011-12-20 23:22:417631 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337632
tfarina42834112016-09-22 13:38:207633 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017634 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337635
7636 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017637 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337638
bnc691fda62016-08-12 00:43:167639 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337641
7642 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017643 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337644
bnc691fda62016-08-12 00:43:167645 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337646
wezca1070932016-05-26 20:30:527647 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337648 EXPECT_EQ(100, response->headers->GetContentLength());
7649}
7650
7651// Test HTTPS connections to a site with a bad certificate, going through a
7652// proxy
bncd16676a2016-07-20 16:23:017653TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037654 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337655
7656 HttpRequestInfo request;
7657 request.method = "GET";
bncce36dca22015-04-21 22:11:237658 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337659
7660 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177661 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7662 "Host: www.example.org:443\r\n"
7663 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337664 };
7665
7666 MockRead proxy_reads[] = {
7667 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067668 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337669 };
7670
7671 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177672 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7673 "Host: www.example.org:443\r\n"
7674 "Proxy-Connection: keep-alive\r\n\r\n"),
7675 MockWrite("GET / HTTP/1.1\r\n"
7676 "Host: www.example.org\r\n"
7677 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337678 };
7679
7680 MockRead data_reads[] = {
7681 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7682 MockRead("HTTP/1.0 200 OK\r\n"),
7683 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7684 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067685 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337686 };
7687
[email protected]31a2bfe2010-02-09 08:03:397688 StaticSocketDataProvider ssl_bad_certificate(
7689 proxy_reads, arraysize(proxy_reads),
7690 proxy_writes, arraysize(proxy_writes));
7691 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7692 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067693 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7694 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337695
[email protected]bb88e1d32013-05-03 23:11:077696 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7697 session_deps_.socket_factory->AddSocketDataProvider(&data);
7698 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7699 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337700
[email protected]49639fa2011-12-20 23:22:417701 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337702
7703 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077704 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337705
danakj1fd259a02016-04-16 03:17:097706 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337708
tfarina42834112016-09-22 13:38:207709 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337711
7712 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017713 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337714
bnc691fda62016-08-12 00:43:167715 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337717
7718 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017719 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337720
bnc691fda62016-08-12 00:43:167721 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337722
wezca1070932016-05-26 20:30:527723 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337724 EXPECT_EQ(100, response->headers->GetContentLength());
7725 }
7726}
7727
[email protected]2df19bb2010-08-25 20:13:467728
7729// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017730TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037731 session_deps_.proxy_service =
7732 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517733 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077734 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467735
7736 HttpRequestInfo request;
7737 request.method = "GET";
bncce36dca22015-04-21 22:11:237738 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467739
7740 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177741 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7742 "Host: www.example.org:443\r\n"
7743 "Proxy-Connection: keep-alive\r\n\r\n"),
7744 MockWrite("GET / HTTP/1.1\r\n"
7745 "Host: www.example.org\r\n"
7746 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467747 };
7748
7749 MockRead data_reads[] = {
7750 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7751 MockRead("HTTP/1.1 200 OK\r\n"),
7752 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7753 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067754 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467755 };
7756
7757 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7758 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067759 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7760 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467761
[email protected]bb88e1d32013-05-03 23:11:077762 session_deps_.socket_factory->AddSocketDataProvider(&data);
7763 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7764 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467765
[email protected]49639fa2011-12-20 23:22:417766 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467767
danakj1fd259a02016-04-16 03:17:097768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467770
tfarina42834112016-09-22 13:38:207771 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467773
7774 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017775 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167776 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467777
wezca1070932016-05-26 20:30:527778 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467779
tbansal2ecbbc72016-10-06 17:15:477780 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467781 EXPECT_TRUE(response->headers->IsKeepAlive());
7782 EXPECT_EQ(200, response->headers->response_code());
7783 EXPECT_EQ(100, response->headers->GetContentLength());
7784 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207785
7786 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167787 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207788 TestLoadTimingNotReusedWithPac(load_timing_info,
7789 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467790}
7791
[email protected]511f6f52010-12-17 03:58:297792// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017793TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037794 session_deps_.proxy_service =
7795 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517796 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077797 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297798
7799 HttpRequestInfo request;
7800 request.method = "GET";
bncce36dca22015-04-21 22:11:237801 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297802
7803 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177804 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7805 "Host: www.example.org:443\r\n"
7806 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297807 };
7808
7809 MockRead data_reads[] = {
7810 MockRead("HTTP/1.1 302 Redirect\r\n"),
7811 MockRead("Location: http://login.example.com/\r\n"),
7812 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067813 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297814 };
7815
7816 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7817 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067818 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297819
[email protected]bb88e1d32013-05-03 23:11:077820 session_deps_.socket_factory->AddSocketDataProvider(&data);
7821 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297822
[email protected]49639fa2011-12-20 23:22:417823 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297824
danakj1fd259a02016-04-16 03:17:097825 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167826 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297827
tfarina42834112016-09-22 13:38:207828 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297830
7831 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017832 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167833 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297834
wezca1070932016-05-26 20:30:527835 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297836
7837 EXPECT_EQ(302, response->headers->response_code());
7838 std::string url;
7839 EXPECT_TRUE(response->headers->IsRedirect(&url));
7840 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207841
7842 // In the case of redirects from proxies, HttpNetworkTransaction returns
7843 // timing for the proxy connection instead of the connection to the host,
7844 // and no send / receive times.
7845 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7846 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167847 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207848
7849 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197850 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207851
7852 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7853 EXPECT_LE(load_timing_info.proxy_resolve_start,
7854 load_timing_info.proxy_resolve_end);
7855 EXPECT_LE(load_timing_info.proxy_resolve_end,
7856 load_timing_info.connect_timing.connect_start);
7857 ExpectConnectTimingHasTimes(
7858 load_timing_info.connect_timing,
7859 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7860
7861 EXPECT_TRUE(load_timing_info.send_start.is_null());
7862 EXPECT_TRUE(load_timing_info.send_end.is_null());
7863 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297864}
7865
7866// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017867TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037868 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297869
7870 HttpRequestInfo request;
7871 request.method = "GET";
bncce36dca22015-04-21 22:11:237872 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297873
bncdf80d44fd2016-07-15 20:27:417874 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237875 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417876 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:087877 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297878 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417879 CreateMockWrite(conn, 0, SYNCHRONOUS),
7880 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297881 };
7882
7883 static const char* const kExtraHeaders[] = {
7884 "location",
7885 "http://login.example.com/",
7886 };
bnc42331402016-07-25 13:36:157887 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237888 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297889 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417890 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297891 };
7892
rch8e6c6c42015-05-01 14:05:137893 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7894 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067895 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367896 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297897
[email protected]bb88e1d32013-05-03 23:11:077898 session_deps_.socket_factory->AddSocketDataProvider(&data);
7899 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297900
[email protected]49639fa2011-12-20 23:22:417901 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297902
danakj1fd259a02016-04-16 03:17:097903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167904 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297905
tfarina42834112016-09-22 13:38:207906 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297908
7909 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017910 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167911 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297912
wezca1070932016-05-26 20:30:527913 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297914
7915 EXPECT_EQ(302, response->headers->response_code());
7916 std::string url;
7917 EXPECT_TRUE(response->headers->IsRedirect(&url));
7918 EXPECT_EQ("http://login.example.com/", url);
7919}
7920
[email protected]4eddbc732012-08-09 05:40:177921// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017922TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037923 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297924
7925 HttpRequestInfo request;
7926 request.method = "GET";
bncce36dca22015-04-21 22:11:237927 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297928
7929 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177930 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7931 "Host: www.example.org:443\r\n"
7932 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297933 };
7934
7935 MockRead data_reads[] = {
7936 MockRead("HTTP/1.1 404 Not Found\r\n"),
7937 MockRead("Content-Length: 23\r\n\r\n"),
7938 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067939 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297940 };
7941
7942 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7943 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067944 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297945
[email protected]bb88e1d32013-05-03 23:11:077946 session_deps_.socket_factory->AddSocketDataProvider(&data);
7947 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297948
[email protected]49639fa2011-12-20 23:22:417949 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297950
danakj1fd259a02016-04-16 03:17:097951 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297953
tfarina42834112016-09-22 13:38:207954 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297956
7957 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017958 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297959
ttuttle960fcbf2016-04-19 13:26:327960 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297961}
7962
[email protected]4eddbc732012-08-09 05:40:177963// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017964TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037965 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297966
7967 HttpRequestInfo request;
7968 request.method = "GET";
bncce36dca22015-04-21 22:11:237969 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297970
bncdf80d44fd2016-07-15 20:27:417971 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237972 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417973 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:087974 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297975 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417976 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297977 };
7978
7979 static const char* const kExtraHeaders[] = {
7980 "location",
7981 "http://login.example.com/",
7982 };
bnc42331402016-07-25 13:36:157983 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237984 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:417985 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557986 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297987 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417988 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137989 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297990 };
7991
rch8e6c6c42015-05-01 14:05:137992 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7993 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067994 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367995 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297996
[email protected]bb88e1d32013-05-03 23:11:077997 session_deps_.socket_factory->AddSocketDataProvider(&data);
7998 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297999
[email protected]49639fa2011-12-20 23:22:418000 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298001
danakj1fd259a02016-04-16 03:17:098002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168003 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298004
tfarina42834112016-09-22 13:38:208005 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298007
8008 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018009 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298010
ttuttle960fcbf2016-04-19 13:26:328011 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298012}
8013
[email protected]0c5fb722012-02-28 11:50:358014// Test the request-challenge-retry sequence for basic auth, through
8015// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018016TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358017 HttpRequestInfo request;
8018 request.method = "GET";
bncce36dca22015-04-21 22:11:238019 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358020 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298021 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358022
8023 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038024 session_deps_.proxy_service =
8025 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518026 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078027 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358029
8030 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418031 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238032 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418033 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088034 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388035 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358036
bnc691fda62016-08-12 00:43:168037 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358038 // be issuing -- the final header line contains the credentials.
8039 const char* const kAuthCredentials[] = {
8040 "proxy-authorization", "Basic Zm9vOmJhcg==",
8041 };
bncdf80d44fd2016-07-15 20:27:418042 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348043 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238044 HostPortPair("www.example.org", 443)));
8045 // fetch https://www.example.org/ via HTTP
8046 const char get[] =
8047 "GET / HTTP/1.1\r\n"
8048 "Host: www.example.org\r\n"
8049 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418050 SpdySerializedFrame wrapped_get(
8051 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358052
8053 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418054 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8055 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358056 };
8057
8058 // The proxy responds to the connect with a 407, using a persistent
8059 // connection.
thestig9d3bb0c2015-01-24 00:49:518060 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358061 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358062 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8063 };
bnc42331402016-07-25 13:36:158064 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418065 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358066
bnc42331402016-07-25 13:36:158067 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358068 const char resp[] = "HTTP/1.1 200 OK\r\n"
8069 "Content-Length: 5\r\n\r\n";
8070
bncdf80d44fd2016-07-15 20:27:418071 SpdySerializedFrame wrapped_get_resp(
8072 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8073 SpdySerializedFrame wrapped_body(
8074 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358075 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418076 CreateMockRead(conn_auth_resp, 1, ASYNC),
8077 CreateMockRead(conn_resp, 4, ASYNC),
8078 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8079 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138080 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358081 };
8082
rch8e6c6c42015-05-01 14:05:138083 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8084 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078085 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358086 // Negotiate SPDY to the proxy
8087 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368088 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078089 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358090 // Vanilla SSL to the server
8091 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078092 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358093
8094 TestCompletionCallback callback1;
8095
bnc87dcefc2017-05-25 12:47:588096 auto trans =
8097 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358098
8099 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018100 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358101
8102 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018103 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468104 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358105 log.GetEntries(&entries);
8106 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008107 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8108 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358109 ExpectLogContainsSomewhere(
8110 entries, pos,
mikecirone8b85c432016-09-08 19:11:008111 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8112 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358113
8114 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528115 ASSERT_TRUE(response);
8116 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358117 EXPECT_EQ(407, response->headers->response_code());
8118 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528119 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438120 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358121
8122 TestCompletionCallback callback2;
8123
8124 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8125 callback2.callback());
robpercival214763f2016-07-01 23:27:018126 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358127
8128 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018129 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358130
8131 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528132 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358133
8134 EXPECT_TRUE(response->headers->IsKeepAlive());
8135 EXPECT_EQ(200, response->headers->response_code());
8136 EXPECT_EQ(5, response->headers->GetContentLength());
8137 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8138
8139 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528140 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358141
[email protected]029c83b62013-01-24 05:28:208142 LoadTimingInfo load_timing_info;
8143 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8144 TestLoadTimingNotReusedWithPac(load_timing_info,
8145 CONNECT_TIMING_HAS_SSL_TIMES);
8146
[email protected]0c5fb722012-02-28 11:50:358147 trans.reset();
8148 session->CloseAllConnections();
8149}
8150
[email protected]7c6f7ba2012-04-03 04:09:298151// Test that an explicitly trusted SPDY proxy can push a resource from an
8152// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018153TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158154 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588155 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158156 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8157 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298158 HttpRequestInfo request;
8159 HttpRequestInfo push_request;
8160
[email protected]7c6f7ba2012-04-03 04:09:298161 request.method = "GET";
bncce36dca22015-04-21 22:11:238162 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298163 push_request.method = "GET";
8164 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8165
tbansal28e68f82016-02-04 02:56:158166 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038167 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158168 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518169 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078170 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508171
inlinechan894515af2016-12-09 02:40:108172 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508173
danakj1fd259a02016-04-16 03:17:098174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298175
bncdf80d44fd2016-07-15 20:27:418176 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458177 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358178 SpdySerializedFrame stream2_priority(
8179 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298180
8181 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418182 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358183 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298184 };
8185
bncdf80d44fd2016-07-15 20:27:418186 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158187 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298188
bncdf80d44fd2016-07-15 20:27:418189 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298190
bncdf80d44fd2016-07-15 20:27:418191 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558192 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438193 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418194 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8195 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298196
8197 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418198 CreateMockRead(stream1_reply, 1, ASYNC),
8199 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358200 CreateMockRead(stream1_body, 4, ASYNC),
8201 CreateMockRead(stream2_body, 5, ASYNC),
8202 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298203 };
8204
rch8e6c6c42015-05-01 14:05:138205 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8206 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078207 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298208 // Negotiate SPDY to the proxy
8209 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368210 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078211 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298212
bnc87dcefc2017-05-25 12:47:588213 auto trans =
8214 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298215 TestCompletionCallback callback;
8216 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298218
8219 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018220 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298221 const HttpResponseInfo* response = trans->GetResponseInfo();
8222
bnc87dcefc2017-05-25 12:47:588223 auto push_trans =
8224 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508225 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018226 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298227
8228 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018229 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298230 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8231
wezca1070932016-05-26 20:30:528232 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298233 EXPECT_TRUE(response->headers->IsKeepAlive());
8234
8235 EXPECT_EQ(200, response->headers->response_code());
8236 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8237
8238 std::string response_data;
8239 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018240 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298241 EXPECT_EQ("hello!", response_data);
8242
[email protected]029c83b62013-01-24 05:28:208243 LoadTimingInfo load_timing_info;
8244 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8245 TestLoadTimingNotReusedWithPac(load_timing_info,
8246 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8247
[email protected]7c6f7ba2012-04-03 04:09:298248 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528249 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298250 EXPECT_EQ(200, push_response->headers->response_code());
8251
8252 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018253 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298254 EXPECT_EQ("pushed", response_data);
8255
[email protected]029c83b62013-01-24 05:28:208256 LoadTimingInfo push_load_timing_info;
8257 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8258 TestLoadTimingReusedWithPac(push_load_timing_info);
8259 // The transactions should share a socket ID, despite being for different
8260 // origins.
8261 EXPECT_EQ(load_timing_info.socket_log_id,
8262 push_load_timing_info.socket_log_id);
8263
[email protected]7c6f7ba2012-04-03 04:09:298264 trans.reset();
8265 push_trans.reset();
8266 session->CloseAllConnections();
8267}
8268
[email protected]8c843192012-04-05 07:15:008269// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018270TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158271 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588272 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158273 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8274 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008275 HttpRequestInfo request;
8276
8277 request.method = "GET";
bncce36dca22015-04-21 22:11:238278 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008279
tbansal28e68f82016-02-04 02:56:158280 session_deps_.proxy_service =
8281 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518282 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078283 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508284
8285 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108286 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508287
danakj1fd259a02016-04-16 03:17:098288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008289
bncdf80d44fd2016-07-15 20:27:418290 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458291 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008292
bncdf80d44fd2016-07-15 20:27:418293 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088294 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008295
8296 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418297 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008298 };
8299
bncdf80d44fd2016-07-15 20:27:418300 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158301 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008302
bncdf80d44fd2016-07-15 20:27:418303 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008304
bncdf80d44fd2016-07-15 20:27:418305 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558306 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008307
8308 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418309 CreateMockRead(stream1_reply, 1, ASYNC),
8310 CreateMockRead(stream2_syn, 2, ASYNC),
8311 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598312 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008313 };
8314
rch8e6c6c42015-05-01 14:05:138315 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8316 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078317 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008318 // Negotiate SPDY to the proxy
8319 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368320 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078321 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008322
bnc87dcefc2017-05-25 12:47:588323 auto trans =
8324 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008325 TestCompletionCallback callback;
8326 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018327 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008328
8329 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018330 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008331 const HttpResponseInfo* response = trans->GetResponseInfo();
8332
wezca1070932016-05-26 20:30:528333 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008334 EXPECT_TRUE(response->headers->IsKeepAlive());
8335
8336 EXPECT_EQ(200, response->headers->response_code());
8337 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8338
8339 std::string response_data;
8340 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018341 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008342 EXPECT_EQ("hello!", response_data);
8343
8344 trans.reset();
8345 session->CloseAllConnections();
8346}
8347
tbansal8ef1d3e2016-02-03 04:05:428348// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8349// resources.
bncd16676a2016-07-20 16:23:018350TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158351 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588352 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158353 proxy_delegate->set_trusted_spdy_proxy(
8354 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8355
tbansal8ef1d3e2016-02-03 04:05:428356 HttpRequestInfo request;
8357
8358 request.method = "GET";
8359 request.url = GURL("http://www.example.org/");
8360
8361 // Configure against https proxy server "myproxy:70".
8362 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8363 BoundTestNetLog log;
8364 session_deps_.net_log = log.bound().net_log();
8365
8366 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108367 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428368
danakj1fd259a02016-04-16 03:17:098369 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428370
bncdf80d44fd2016-07-15 20:27:418371 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458372 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358373 SpdySerializedFrame stream2_priority(
8374 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428375
8376 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418377 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358378 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428379 };
8380
bncdf80d44fd2016-07-15 20:27:418381 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158382 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428383
bncdf80d44fd2016-07-15 20:27:418384 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498385 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8386
bncdf80d44fd2016-07-15 20:27:418387 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428388
bncdf80d44fd2016-07-15 20:27:418389 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158390 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428391
bncdf80d44fd2016-07-15 20:27:418392 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428393
8394 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418395 CreateMockRead(stream1_reply, 1, ASYNC),
8396 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358397 CreateMockRead(stream1_body, 4, ASYNC),
8398 CreateMockRead(stream2_body, 5, ASYNC),
8399 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428400 };
8401
8402 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8403 arraysize(spdy_writes));
8404 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8405 // Negotiate SPDY to the proxy
8406 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368407 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428408 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8409
bnc87dcefc2017-05-25 12:47:588410 auto trans =
8411 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428412 TestCompletionCallback callback;
8413 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428415
8416 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018417 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428418 const HttpResponseInfo* response = trans->GetResponseInfo();
8419
wezca1070932016-05-26 20:30:528420 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428421 EXPECT_TRUE(response->headers->IsKeepAlive());
8422
8423 EXPECT_EQ(200, response->headers->response_code());
8424 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8425
8426 std::string response_data;
8427 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018428 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428429 EXPECT_EQ("hello!", response_data);
8430
8431 trans.reset();
8432 session->CloseAllConnections();
8433}
8434
[email protected]2df19bb2010-08-25 20:13:468435// Test HTTPS connections to a site with a bad certificate, going through an
8436// HTTPS proxy
bncd16676a2016-07-20 16:23:018437TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038438 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468439
8440 HttpRequestInfo request;
8441 request.method = "GET";
bncce36dca22015-04-21 22:11:238442 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468443
8444 // Attempt to fetch the URL from a server with a bad cert
8445 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178446 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8447 "Host: www.example.org:443\r\n"
8448 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468449 };
8450
8451 MockRead bad_cert_reads[] = {
8452 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068453 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468454 };
8455
8456 // Attempt to fetch the URL with a good cert
8457 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178458 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8459 "Host: www.example.org:443\r\n"
8460 "Proxy-Connection: keep-alive\r\n\r\n"),
8461 MockWrite("GET / HTTP/1.1\r\n"
8462 "Host: www.example.org\r\n"
8463 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468464 };
8465
8466 MockRead good_cert_reads[] = {
8467 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8468 MockRead("HTTP/1.0 200 OK\r\n"),
8469 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8470 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068471 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468472 };
8473
8474 StaticSocketDataProvider ssl_bad_certificate(
8475 bad_cert_reads, arraysize(bad_cert_reads),
8476 bad_cert_writes, arraysize(bad_cert_writes));
8477 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8478 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068479 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8480 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468481
8482 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078483 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8484 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8485 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468486
8487 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078488 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8489 session_deps_.socket_factory->AddSocketDataProvider(&data);
8490 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468491
[email protected]49639fa2011-12-20 23:22:418492 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468493
danakj1fd259a02016-04-16 03:17:098494 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168495 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468496
tfarina42834112016-09-22 13:38:208497 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468499
8500 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018501 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468502
bnc691fda62016-08-12 00:43:168503 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018504 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468505
8506 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018507 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468508
bnc691fda62016-08-12 00:43:168509 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468510
wezca1070932016-05-26 20:30:528511 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468512 EXPECT_EQ(100, response->headers->GetContentLength());
8513}
8514
bncd16676a2016-07-20 16:23:018515TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428516 HttpRequestInfo request;
8517 request.method = "GET";
bncce36dca22015-04-21 22:11:238518 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438519 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8520 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428521
danakj1fd259a02016-04-16 03:17:098522 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168523 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278524
[email protected]1c773ea12009-04-28 19:58:428525 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238526 MockWrite(
8527 "GET / HTTP/1.1\r\n"
8528 "Host: www.example.org\r\n"
8529 "Connection: keep-alive\r\n"
8530 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428531 };
8532
8533 // Lastly, the server responds with the actual content.
8534 MockRead data_reads[] = {
8535 MockRead("HTTP/1.0 200 OK\r\n"),
8536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8537 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068538 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428539 };
8540
[email protected]31a2bfe2010-02-09 08:03:398541 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8542 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078543 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428544
[email protected]49639fa2011-12-20 23:22:418545 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428546
tfarina42834112016-09-22 13:38:208547 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018548 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428549
8550 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018551 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428552}
8553
bncd16676a2016-07-20 16:23:018554TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298555 HttpRequestInfo request;
8556 request.method = "GET";
bncce36dca22015-04-21 22:11:238557 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298558 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8559 "Chromium Ultra Awesome X Edition");
8560
rdsmith82957ad2015-09-16 19:42:038561 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098562 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168563 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278564
[email protected]da81f132010-08-18 23:39:298565 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178566 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8567 "Host: www.example.org:443\r\n"
8568 "Proxy-Connection: keep-alive\r\n"
8569 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298570 };
8571 MockRead data_reads[] = {
8572 // Return an error, so the transaction stops here (this test isn't
8573 // interested in the rest).
8574 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8575 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8576 MockRead("Proxy-Connection: close\r\n\r\n"),
8577 };
8578
8579 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8580 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078581 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298582
[email protected]49639fa2011-12-20 23:22:418583 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298584
tfarina42834112016-09-22 13:38:208585 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298587
8588 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018589 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298590}
8591
bncd16676a2016-07-20 16:23:018592TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428593 HttpRequestInfo request;
8594 request.method = "GET";
bncce36dca22015-04-21 22:11:238595 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168596 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8597 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428598
danakj1fd259a02016-04-16 03:17:098599 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278601
[email protected]1c773ea12009-04-28 19:58:428602 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238603 MockWrite(
8604 "GET / HTTP/1.1\r\n"
8605 "Host: www.example.org\r\n"
8606 "Connection: keep-alive\r\n"
8607 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428608 };
8609
8610 // Lastly, the server responds with the actual content.
8611 MockRead data_reads[] = {
8612 MockRead("HTTP/1.0 200 OK\r\n"),
8613 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8614 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068615 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428616 };
8617
[email protected]31a2bfe2010-02-09 08:03:398618 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8619 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078620 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428621
[email protected]49639fa2011-12-20 23:22:418622 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428623
tfarina42834112016-09-22 13:38:208624 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428626
8627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018628 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428629}
8630
bncd16676a2016-07-20 16:23:018631TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428632 HttpRequestInfo request;
8633 request.method = "POST";
bncce36dca22015-04-21 22:11:238634 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428635
danakj1fd259a02016-04-16 03:17:098636 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168637 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278638
[email protected]1c773ea12009-04-28 19:58:428639 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238640 MockWrite(
8641 "POST / HTTP/1.1\r\n"
8642 "Host: www.example.org\r\n"
8643 "Connection: keep-alive\r\n"
8644 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428645 };
8646
8647 // Lastly, the server responds with the actual content.
8648 MockRead data_reads[] = {
8649 MockRead("HTTP/1.0 200 OK\r\n"),
8650 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8651 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068652 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428653 };
8654
[email protected]31a2bfe2010-02-09 08:03:398655 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8656 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078657 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428658
[email protected]49639fa2011-12-20 23:22:418659 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428660
tfarina42834112016-09-22 13:38:208661 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428663
8664 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018665 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428666}
8667
bncd16676a2016-07-20 16:23:018668TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428669 HttpRequestInfo request;
8670 request.method = "PUT";
bncce36dca22015-04-21 22:11:238671 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428672
danakj1fd259a02016-04-16 03:17:098673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168674 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278675
[email protected]1c773ea12009-04-28 19:58:428676 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238677 MockWrite(
8678 "PUT / HTTP/1.1\r\n"
8679 "Host: www.example.org\r\n"
8680 "Connection: keep-alive\r\n"
8681 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428682 };
8683
8684 // Lastly, the server responds with the actual content.
8685 MockRead data_reads[] = {
8686 MockRead("HTTP/1.0 200 OK\r\n"),
8687 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8688 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068689 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428690 };
8691
[email protected]31a2bfe2010-02-09 08:03:398692 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8693 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078694 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428695
[email protected]49639fa2011-12-20 23:22:418696 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428697
tfarina42834112016-09-22 13:38:208698 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428700
8701 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018702 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428703}
8704
bncd16676a2016-07-20 16:23:018705TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428706 HttpRequestInfo request;
8707 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238708 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428709
danakj1fd259a02016-04-16 03:17:098710 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278712
[email protected]1c773ea12009-04-28 19:58:428713 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138714 MockWrite("HEAD / HTTP/1.1\r\n"
8715 "Host: www.example.org\r\n"
8716 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428717 };
8718
8719 // Lastly, the server responds with the actual content.
8720 MockRead data_reads[] = {
8721 MockRead("HTTP/1.0 200 OK\r\n"),
8722 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8723 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068724 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428725 };
8726
[email protected]31a2bfe2010-02-09 08:03:398727 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8728 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078729 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428730
[email protected]49639fa2011-12-20 23:22:418731 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428732
tfarina42834112016-09-22 13:38:208733 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428735
8736 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018737 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428738}
8739
bncd16676a2016-07-20 16:23:018740TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428741 HttpRequestInfo request;
8742 request.method = "GET";
bncce36dca22015-04-21 22:11:238743 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428744 request.load_flags = LOAD_BYPASS_CACHE;
8745
danakj1fd259a02016-04-16 03:17:098746 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168747 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278748
[email protected]1c773ea12009-04-28 19:58:428749 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238750 MockWrite(
8751 "GET / HTTP/1.1\r\n"
8752 "Host: www.example.org\r\n"
8753 "Connection: keep-alive\r\n"
8754 "Pragma: no-cache\r\n"
8755 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428756 };
8757
8758 // Lastly, the server responds with the actual content.
8759 MockRead data_reads[] = {
8760 MockRead("HTTP/1.0 200 OK\r\n"),
8761 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8762 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068763 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428764 };
8765
[email protected]31a2bfe2010-02-09 08:03:398766 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8767 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078768 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428769
[email protected]49639fa2011-12-20 23:22:418770 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428771
tfarina42834112016-09-22 13:38:208772 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428774
8775 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018776 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428777}
8778
bncd16676a2016-07-20 16:23:018779TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428780 HttpRequestInfo request;
8781 request.method = "GET";
bncce36dca22015-04-21 22:11:238782 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428783 request.load_flags = LOAD_VALIDATE_CACHE;
8784
danakj1fd259a02016-04-16 03:17:098785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168786 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278787
[email protected]1c773ea12009-04-28 19:58:428788 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238789 MockWrite(
8790 "GET / HTTP/1.1\r\n"
8791 "Host: www.example.org\r\n"
8792 "Connection: keep-alive\r\n"
8793 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428794 };
8795
8796 // Lastly, the server responds with the actual content.
8797 MockRead data_reads[] = {
8798 MockRead("HTTP/1.0 200 OK\r\n"),
8799 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8800 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068801 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428802 };
8803
[email protected]31a2bfe2010-02-09 08:03:398804 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8805 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078806 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428807
[email protected]49639fa2011-12-20 23:22:418808 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428809
tfarina42834112016-09-22 13:38:208810 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428812
8813 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018814 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428815}
8816
bncd16676a2016-07-20 16:23:018817TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428818 HttpRequestInfo request;
8819 request.method = "GET";
bncce36dca22015-04-21 22:11:238820 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438821 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428822
danakj1fd259a02016-04-16 03:17:098823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278825
[email protected]1c773ea12009-04-28 19:58:428826 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238827 MockWrite(
8828 "GET / HTTP/1.1\r\n"
8829 "Host: www.example.org\r\n"
8830 "Connection: keep-alive\r\n"
8831 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428832 };
8833
8834 // Lastly, the server responds with the actual content.
8835 MockRead data_reads[] = {
8836 MockRead("HTTP/1.0 200 OK\r\n"),
8837 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8838 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068839 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428840 };
8841
[email protected]31a2bfe2010-02-09 08:03:398842 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8843 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078844 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428845
[email protected]49639fa2011-12-20 23:22:418846 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428847
tfarina42834112016-09-22 13:38:208848 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018849 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428850
8851 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018852 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428853}
8854
bncd16676a2016-07-20 16:23:018855TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478856 HttpRequestInfo request;
8857 request.method = "GET";
bncce36dca22015-04-21 22:11:238858 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438859 request.extra_headers.SetHeader("referer", "www.foo.com");
8860 request.extra_headers.SetHeader("hEllo", "Kitty");
8861 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478862
danakj1fd259a02016-04-16 03:17:098863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168864 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278865
[email protected]270c6412010-03-29 22:02:478866 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238867 MockWrite(
8868 "GET / HTTP/1.1\r\n"
8869 "Host: www.example.org\r\n"
8870 "Connection: keep-alive\r\n"
8871 "referer: www.foo.com\r\n"
8872 "hEllo: Kitty\r\n"
8873 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478874 };
8875
8876 // Lastly, the server responds with the actual content.
8877 MockRead data_reads[] = {
8878 MockRead("HTTP/1.0 200 OK\r\n"),
8879 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8880 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068881 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478882 };
8883
8884 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8885 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078886 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478887
[email protected]49639fa2011-12-20 23:22:418888 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478889
tfarina42834112016-09-22 13:38:208890 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478892
8893 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018894 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478895}
8896
bncd16676a2016-07-20 16:23:018897TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278898 HttpRequestInfo request;
8899 request.method = "GET";
bncce36dca22015-04-21 22:11:238900 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278901
rdsmith82957ad2015-09-16 19:42:038902 session_deps_.proxy_service =
8903 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518904 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078905 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028906
danakj1fd259a02016-04-16 03:17:098907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168908 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028909
[email protected]3cd17242009-06-23 02:59:028910 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8911 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8912
8913 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238914 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8915 MockWrite(
8916 "GET / HTTP/1.1\r\n"
8917 "Host: www.example.org\r\n"
8918 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028919
8920 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068921 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028922 MockRead("HTTP/1.0 200 OK\r\n"),
8923 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8924 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068925 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028926 };
8927
[email protected]31a2bfe2010-02-09 08:03:398928 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8929 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078930 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028931
[email protected]49639fa2011-12-20 23:22:418932 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028933
tfarina42834112016-09-22 13:38:208934 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018935 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028936
8937 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018938 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028939
bnc691fda62016-08-12 00:43:168940 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528941 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028942
tbansal2ecbbc72016-10-06 17:15:478943 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208944 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168945 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208946 TestLoadTimingNotReusedWithPac(load_timing_info,
8947 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8948
[email protected]3cd17242009-06-23 02:59:028949 std::string response_text;
bnc691fda62016-08-12 00:43:168950 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018951 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028952 EXPECT_EQ("Payload", response_text);
8953}
8954
bncd16676a2016-07-20 16:23:018955TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278956 HttpRequestInfo request;
8957 request.method = "GET";
bncce36dca22015-04-21 22:11:238958 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278959
rdsmith82957ad2015-09-16 19:42:038960 session_deps_.proxy_service =
8961 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518962 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078963 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028964
danakj1fd259a02016-04-16 03:17:098965 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168966 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028967
[email protected]3cd17242009-06-23 02:59:028968 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8969 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8970
8971 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238972 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8973 arraysize(write_buffer)),
8974 MockWrite(
8975 "GET / HTTP/1.1\r\n"
8976 "Host: www.example.org\r\n"
8977 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028978
8979 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018980 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8981 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358982 MockRead("HTTP/1.0 200 OK\r\n"),
8983 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8984 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068985 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358986 };
8987
[email protected]31a2bfe2010-02-09 08:03:398988 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8989 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078990 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358991
[email protected]8ddf8322012-02-23 18:08:068992 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078993 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358994
[email protected]49639fa2011-12-20 23:22:418995 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358996
tfarina42834112016-09-22 13:38:208997 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358999
9000 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019001 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359002
[email protected]029c83b62013-01-24 05:28:209003 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169004 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209005 TestLoadTimingNotReusedWithPac(load_timing_info,
9006 CONNECT_TIMING_HAS_SSL_TIMES);
9007
bnc691fda62016-08-12 00:43:169008 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529009 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479010 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359011
9012 std::string response_text;
bnc691fda62016-08-12 00:43:169013 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019014 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359015 EXPECT_EQ("Payload", response_text);
9016}
9017
bncd16676a2016-07-20 16:23:019018TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209019 HttpRequestInfo request;
9020 request.method = "GET";
bncce36dca22015-04-21 22:11:239021 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209022
rdsmith82957ad2015-09-16 19:42:039023 session_deps_.proxy_service =
9024 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519025 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079026 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209027
danakj1fd259a02016-04-16 03:17:099028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209030
9031 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9032 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9033
9034 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239035 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9036 MockWrite(
9037 "GET / HTTP/1.1\r\n"
9038 "Host: www.example.org\r\n"
9039 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209040
9041 MockRead data_reads[] = {
9042 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9043 MockRead("HTTP/1.0 200 OK\r\n"),
9044 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9045 MockRead("Payload"),
9046 MockRead(SYNCHRONOUS, OK)
9047 };
9048
9049 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9050 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079051 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209052
9053 TestCompletionCallback callback;
9054
tfarina42834112016-09-22 13:38:209055 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209057
9058 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019059 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209060
bnc691fda62016-08-12 00:43:169061 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529062 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209063
9064 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169065 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209066 TestLoadTimingNotReused(load_timing_info,
9067 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9068
9069 std::string response_text;
bnc691fda62016-08-12 00:43:169070 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019071 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209072 EXPECT_EQ("Payload", response_text);
9073}
9074
bncd16676a2016-07-20 16:23:019075TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279076 HttpRequestInfo request;
9077 request.method = "GET";
bncce36dca22015-04-21 22:11:239078 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279079
rdsmith82957ad2015-09-16 19:42:039080 session_deps_.proxy_service =
9081 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519082 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079083 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359084
danakj1fd259a02016-04-16 03:17:099085 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169086 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359087
[email protected]e0c27be2009-07-15 13:09:359088 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9089 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379090 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239091 0x05, // Version
9092 0x01, // Command (CONNECT)
9093 0x00, // Reserved.
9094 0x03, // Address type (DOMAINNAME).
9095 0x0F, // Length of domain (15)
9096 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9097 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379098 };
[email protected]e0c27be2009-07-15 13:09:359099 const char kSOCKS5OkResponse[] =
9100 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9101
9102 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239103 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9104 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9105 MockWrite(
9106 "GET / HTTP/1.1\r\n"
9107 "Host: www.example.org\r\n"
9108 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359109
9110 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019111 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9112 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359113 MockRead("HTTP/1.0 200 OK\r\n"),
9114 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9115 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069116 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359117 };
9118
[email protected]31a2bfe2010-02-09 08:03:399119 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9120 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079121 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359122
[email protected]49639fa2011-12-20 23:22:419123 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359124
tfarina42834112016-09-22 13:38:209125 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019126 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359127
9128 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019129 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359130
bnc691fda62016-08-12 00:43:169131 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529132 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479133 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359134
[email protected]029c83b62013-01-24 05:28:209135 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169136 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209137 TestLoadTimingNotReusedWithPac(load_timing_info,
9138 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9139
[email protected]e0c27be2009-07-15 13:09:359140 std::string response_text;
bnc691fda62016-08-12 00:43:169141 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019142 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359143 EXPECT_EQ("Payload", response_text);
9144}
9145
bncd16676a2016-07-20 16:23:019146TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279147 HttpRequestInfo request;
9148 request.method = "GET";
bncce36dca22015-04-21 22:11:239149 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279150
rdsmith82957ad2015-09-16 19:42:039151 session_deps_.proxy_service =
9152 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519153 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079154 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359155
danakj1fd259a02016-04-16 03:17:099156 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169157 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359158
[email protected]e0c27be2009-07-15 13:09:359159 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9160 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379161 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239162 0x05, // Version
9163 0x01, // Command (CONNECT)
9164 0x00, // Reserved.
9165 0x03, // Address type (DOMAINNAME).
9166 0x0F, // Length of domain (15)
9167 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9168 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379169 };
9170
[email protected]e0c27be2009-07-15 13:09:359171 const char kSOCKS5OkResponse[] =
9172 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9173
9174 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239175 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9176 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9177 arraysize(kSOCKS5OkRequest)),
9178 MockWrite(
9179 "GET / HTTP/1.1\r\n"
9180 "Host: www.example.org\r\n"
9181 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359182
9183 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019184 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9185 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029186 MockRead("HTTP/1.0 200 OK\r\n"),
9187 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9188 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069189 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029190 };
9191
[email protected]31a2bfe2010-02-09 08:03:399192 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9193 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079194 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029195
[email protected]8ddf8322012-02-23 18:08:069196 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079197 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029198
[email protected]49639fa2011-12-20 23:22:419199 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029200
tfarina42834112016-09-22 13:38:209201 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029203
9204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019205 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029206
bnc691fda62016-08-12 00:43:169207 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529208 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479209 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029210
[email protected]029c83b62013-01-24 05:28:209211 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169212 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209213 TestLoadTimingNotReusedWithPac(load_timing_info,
9214 CONNECT_TIMING_HAS_SSL_TIMES);
9215
[email protected]3cd17242009-06-23 02:59:029216 std::string response_text;
bnc691fda62016-08-12 00:43:169217 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019218 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029219 EXPECT_EQ("Payload", response_text);
9220}
9221
[email protected]448d4ca52012-03-04 04:12:239222namespace {
9223
[email protected]04e5be32009-06-26 20:00:319224// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069225
9226struct GroupNameTest {
9227 std::string proxy_server;
9228 std::string url;
9229 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189230 bool ssl;
[email protected]2d731a32010-04-29 01:04:069231};
9232
danakj1fd259a02016-04-16 03:17:099233std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079234 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099235 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069236
bnc525e175a2016-06-20 12:36:409237 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539238 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219239 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129240 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229241 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429242 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469243 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069244
9245 return session;
9246}
9247
mmenkee65e7af2015-10-13 17:16:429248int GroupNameTransactionHelper(const std::string& url,
9249 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069250 HttpRequestInfo request;
9251 request.method = "GET";
9252 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069253
bnc691fda62016-08-12 00:43:169254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279255
[email protected]49639fa2011-12-20 23:22:419256 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069257
9258 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209259 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069260}
9261
[email protected]448d4ca52012-03-04 04:12:239262} // namespace
9263
bncd16676a2016-07-20 16:23:019264TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069265 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239266 {
9267 "", // unused
9268 "http://www.example.org/direct",
9269 "www.example.org:80",
9270 false,
9271 },
9272 {
9273 "", // unused
9274 "http://[2001:1418:13:1::25]/direct",
9275 "[2001:1418:13:1::25]:80",
9276 false,
9277 },
[email protected]04e5be32009-06-26 20:00:319278
bncce36dca22015-04-21 22:11:239279 // SSL Tests
9280 {
9281 "", // unused
9282 "https://www.example.org/direct_ssl",
9283 "ssl/www.example.org:443",
9284 true,
9285 },
9286 {
9287 "", // unused
9288 "https://[2001:1418:13:1::25]/direct",
9289 "ssl/[2001:1418:13:1::25]:443",
9290 true,
9291 },
9292 {
9293 "", // unused
bncaa60ff402016-06-22 19:12:429294 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239295 "ssl/host.with.alternate:443",
9296 true,
9297 },
[email protected]2d731a32010-04-29 01:04:069298 };
[email protected]2ff8b312010-04-26 22:20:549299
viettrungluue4a8b882014-10-16 06:17:389300 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039301 session_deps_.proxy_service =
9302 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099303 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409304 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069305
mmenkee65e7af2015-10-13 17:16:429306 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289307 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589308 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139309 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589310 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
9311 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029312 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9313 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489314 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069315
9316 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429317 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189318 if (tests[i].ssl)
9319 EXPECT_EQ(tests[i].expected_group_name,
9320 ssl_conn_pool->last_group_name_received());
9321 else
9322 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289323 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069324 }
[email protected]2d731a32010-04-29 01:04:069325}
9326
bncd16676a2016-07-20 16:23:019327TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069328 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239329 {
9330 "http_proxy",
9331 "http://www.example.org/http_proxy_normal",
9332 "www.example.org:80",
9333 false,
9334 },
[email protected]2d731a32010-04-29 01:04:069335
bncce36dca22015-04-21 22:11:239336 // SSL Tests
9337 {
9338 "http_proxy",
9339 "https://www.example.org/http_connect_ssl",
9340 "ssl/www.example.org:443",
9341 true,
9342 },
[email protected]af3490e2010-10-16 21:02:299343
bncce36dca22015-04-21 22:11:239344 {
9345 "http_proxy",
bncaa60ff402016-06-22 19:12:429346 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239347 "ssl/host.with.alternate:443",
9348 true,
9349 },
[email protected]45499252013-01-23 17:12:569350
bncce36dca22015-04-21 22:11:239351 {
9352 "http_proxy",
9353 "ftp://ftp.google.com/http_proxy_normal",
9354 "ftp/ftp.google.com:21",
9355 false,
9356 },
[email protected]2d731a32010-04-29 01:04:069357 };
9358
viettrungluue4a8b882014-10-16 06:17:389359 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039360 session_deps_.proxy_service =
9361 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099362 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409363 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069364
mmenkee65e7af2015-10-13 17:16:429365 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069366
[email protected]e60e47a2010-07-14 03:37:189367 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139368 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349369 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139370 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349371 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589372 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399373 mock_pool_manager->SetSocketPoolForHTTPProxy(
9374 proxy_host, base::WrapUnique(http_proxy_pool));
9375 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9376 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489377 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069378
9379 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429380 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189381 if (tests[i].ssl)
9382 EXPECT_EQ(tests[i].expected_group_name,
9383 ssl_conn_pool->last_group_name_received());
9384 else
9385 EXPECT_EQ(tests[i].expected_group_name,
9386 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069387 }
[email protected]2d731a32010-04-29 01:04:069388}
9389
bncd16676a2016-07-20 16:23:019390TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069391 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239392 {
9393 "socks4://socks_proxy:1080",
9394 "http://www.example.org/socks4_direct",
9395 "socks4/www.example.org:80",
9396 false,
9397 },
9398 {
9399 "socks5://socks_proxy:1080",
9400 "http://www.example.org/socks5_direct",
9401 "socks5/www.example.org:80",
9402 false,
9403 },
[email protected]2d731a32010-04-29 01:04:069404
bncce36dca22015-04-21 22:11:239405 // SSL Tests
9406 {
9407 "socks4://socks_proxy:1080",
9408 "https://www.example.org/socks4_ssl",
9409 "socks4/ssl/www.example.org:443",
9410 true,
9411 },
9412 {
9413 "socks5://socks_proxy:1080",
9414 "https://www.example.org/socks5_ssl",
9415 "socks5/ssl/www.example.org:443",
9416 true,
9417 },
[email protected]af3490e2010-10-16 21:02:299418
bncce36dca22015-04-21 22:11:239419 {
9420 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429421 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239422 "socks4/ssl/host.with.alternate:443",
9423 true,
9424 },
[email protected]04e5be32009-06-26 20:00:319425 };
9426
viettrungluue4a8b882014-10-16 06:17:389427 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039428 session_deps_.proxy_service =
9429 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099430 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409431 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029432
mmenkee65e7af2015-10-13 17:16:429433 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319434
[email protected]e60e47a2010-07-14 03:37:189435 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139436 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349437 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139438 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349439 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589440 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399441 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9442 proxy_host, base::WrapUnique(socks_conn_pool));
9443 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9444 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489445 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319446
bnc691fda62016-08-12 00:43:169447 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319448
[email protected]2d731a32010-04-29 01:04:069449 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429450 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189451 if (tests[i].ssl)
9452 EXPECT_EQ(tests[i].expected_group_name,
9453 ssl_conn_pool->last_group_name_received());
9454 else
9455 EXPECT_EQ(tests[i].expected_group_name,
9456 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319457 }
9458}
9459
bncd16676a2016-07-20 16:23:019460TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279461 HttpRequestInfo request;
9462 request.method = "GET";
bncce36dca22015-04-21 22:11:239463 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279464
rdsmith82957ad2015-09-16 19:42:039465 session_deps_.proxy_service =
9466 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329467
[email protected]69719062010-01-05 20:09:219468 // This simulates failure resolving all hostnames; that means we will fail
9469 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079470 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329471
danakj1fd259a02016-04-16 03:17:099472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259474
[email protected]49639fa2011-12-20 23:22:419475 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259476
tfarina42834112016-09-22 13:38:209477 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259479
[email protected]9172a982009-06-06 00:30:259480 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019481 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259482}
9483
[email protected]685af592010-05-11 19:31:249484// Base test to make sure that when the load flags for a request specify to
9485// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029486void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079487 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279488 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109489 HttpRequestInfo request_info;
9490 request_info.method = "GET";
9491 request_info.load_flags = load_flags;
9492 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279493
[email protected]a2c2fb92009-07-18 07:31:049494 // Select a host resolver that does caching.
bnc87dcefc2017-05-25 12:47:589495 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329496
danakj1fd259a02016-04-16 03:17:099497 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169498 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289499
bncce36dca22015-04-21 22:11:239500 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289501 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299502 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109503 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079504 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239505 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109506 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209507 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019508 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479509 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019510 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289511
9512 // Verify that it was added to host cache, by doing a subsequent async lookup
9513 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109514 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079515 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239516 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109517 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209518 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019519 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289520
bncce36dca22015-04-21 22:11:239521 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289522 // we can tell if the next lookup hit the cache, or the "network".
9523 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239524 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289525
9526 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9527 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069528 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399529 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079530 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289531
[email protected]3b9cca42009-06-16 01:08:289532 // Run the request.
tfarina42834112016-09-22 13:38:209533 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019534 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419535 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289536
9537 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239538 // "www.example.org".
robpercival214763f2016-07-01 23:27:019539 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289540}
9541
[email protected]685af592010-05-11 19:31:249542// There are multiple load flags that should trigger the host cache bypass.
9543// Test each in isolation:
bncd16676a2016-07-20 16:23:019544TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249545 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9546}
9547
bncd16676a2016-07-20 16:23:019548TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249549 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9550}
9551
bncd16676a2016-07-20 16:23:019552TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249553 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9554}
9555
[email protected]0877e3d2009-10-17 22:29:579556// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019557TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579558 HttpRequestInfo request;
9559 request.method = "GET";
9560 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579561
9562 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069563 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579564 };
[email protected]31a2bfe2010-02-09 08:03:399565 StaticSocketDataProvider data(NULL, 0,
9566 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079567 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579569
[email protected]49639fa2011-12-20 23:22:419570 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579571
bnc691fda62016-08-12 00:43:169572 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579573
tfarina42834112016-09-22 13:38:209574 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579576
9577 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019578 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599579
9580 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169581 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599582 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579583}
9584
zmo9528c9f42015-08-04 22:12:089585// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019586TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579587 HttpRequestInfo request;
9588 request.method = "GET";
9589 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579590
9591 MockRead data_reads[] = {
9592 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069593 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579594 };
9595
[email protected]31a2bfe2010-02-09 08:03:399596 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079597 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579599
[email protected]49639fa2011-12-20 23:22:419600 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579601
bnc691fda62016-08-12 00:43:169602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579603
tfarina42834112016-09-22 13:38:209604 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579606
9607 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019608 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089609
bnc691fda62016-08-12 00:43:169610 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529611 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089612
wezca1070932016-05-26 20:30:529613 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089614 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9615
9616 std::string response_data;
bnc691fda62016-08-12 00:43:169617 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019618 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089619 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599620
9621 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169622 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599623 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579624}
9625
9626// Make sure that a dropped connection while draining the body for auth
9627// restart does the right thing.
bncd16676a2016-07-20 16:23:019628TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579629 HttpRequestInfo request;
9630 request.method = "GET";
bncce36dca22015-04-21 22:11:239631 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579632
9633 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239634 MockWrite(
9635 "GET / HTTP/1.1\r\n"
9636 "Host: www.example.org\r\n"
9637 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579638 };
9639
9640 MockRead data_reads1[] = {
9641 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9642 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9643 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9644 MockRead("Content-Length: 14\r\n\r\n"),
9645 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069646 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579647 };
9648
[email protected]31a2bfe2010-02-09 08:03:399649 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9650 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079651 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579652
bnc691fda62016-08-12 00:43:169653 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579654 // be issuing -- the final header line contains the credentials.
9655 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239656 MockWrite(
9657 "GET / HTTP/1.1\r\n"
9658 "Host: www.example.org\r\n"
9659 "Connection: keep-alive\r\n"
9660 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579661 };
9662
9663 // Lastly, the server responds with the actual content.
9664 MockRead data_reads2[] = {
9665 MockRead("HTTP/1.1 200 OK\r\n"),
9666 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9667 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069668 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579669 };
9670
[email protected]31a2bfe2010-02-09 08:03:399671 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9672 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079673 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579675
[email protected]49639fa2011-12-20 23:22:419676 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579677
bnc691fda62016-08-12 00:43:169678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509679
tfarina42834112016-09-22 13:38:209680 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579682
9683 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019684 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579685
bnc691fda62016-08-12 00:43:169686 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529687 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049688 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579689
[email protected]49639fa2011-12-20 23:22:419690 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579691
bnc691fda62016-08-12 00:43:169692 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579694
9695 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019696 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579697
bnc691fda62016-08-12 00:43:169698 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529699 ASSERT_TRUE(response);
9700 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579701 EXPECT_EQ(100, response->headers->GetContentLength());
9702}
9703
9704// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019705TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039706 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579707
9708 HttpRequestInfo request;
9709 request.method = "GET";
bncce36dca22015-04-21 22:11:239710 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579711
9712 MockRead proxy_reads[] = {
9713 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069714 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579715 };
9716
[email protected]31a2bfe2010-02-09 08:03:399717 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069718 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579719
[email protected]bb88e1d32013-05-03 23:11:079720 session_deps_.socket_factory->AddSocketDataProvider(&data);
9721 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579722
[email protected]49639fa2011-12-20 23:22:419723 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579724
[email protected]bb88e1d32013-05-03 23:11:079725 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579726
danakj1fd259a02016-04-16 03:17:099727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579729
tfarina42834112016-09-22 13:38:209730 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579732
9733 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019734 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579735}
9736
bncd16676a2016-07-20 16:23:019737TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469738 HttpRequestInfo request;
9739 request.method = "GET";
bncce36dca22015-04-21 22:11:239740 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469741
danakj1fd259a02016-04-16 03:17:099742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279744
[email protected]e22e1362009-11-23 21:31:129745 MockRead data_reads[] = {
9746 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069747 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129748 };
[email protected]9492e4a2010-02-24 00:58:469749
9750 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079751 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469752
[email protected]49639fa2011-12-20 23:22:419753 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469754
tfarina42834112016-09-22 13:38:209755 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469757
robpercival214763f2016-07-01 23:27:019758 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469759
bnc691fda62016-08-12 00:43:169760 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529761 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469762
wezca1070932016-05-26 20:30:529763 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469764 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9765
9766 std::string response_data;
bnc691fda62016-08-12 00:43:169767 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019768 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129769}
9770
bncd16676a2016-07-20 16:23:019771TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159772 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529773 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149774 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219775 UploadFileElementReader::ScopedOverridingContentLengthForTests
9776 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339777
danakj1fd259a02016-04-16 03:17:099778 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079779 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149780 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079781 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229782 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279783
9784 HttpRequestInfo request;
9785 request.method = "POST";
bncce36dca22015-04-21 22:11:239786 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279787 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279788
danakj1fd259a02016-04-16 03:17:099789 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339791
9792 MockRead data_reads[] = {
9793 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9794 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069795 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339796 };
[email protected]31a2bfe2010-02-09 08:03:399797 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079798 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339799
[email protected]49639fa2011-12-20 23:22:419800 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339801
tfarina42834112016-09-22 13:38:209802 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339804
9805 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019806 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339807
bnc691fda62016-08-12 00:43:169808 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529809 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339810
maksim.sisove869bf52016-06-23 17:11:529811 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339812
[email protected]dd3aa792013-07-16 19:10:239813 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339814}
9815
bncd16676a2016-07-20 16:23:019816TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159817 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529818 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369819 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:489820 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
9821 base::WriteFile(temp_file, temp_file_content.c_str(),
9822 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119823 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369824
danakj1fd259a02016-04-16 03:17:099825 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079826 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149827 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079828 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229829 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279830
9831 HttpRequestInfo request;
9832 request.method = "POST";
bncce36dca22015-04-21 22:11:239833 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279834 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279835
[email protected]999dd8c2013-11-12 06:45:549836 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099837 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169838 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369839
[email protected]999dd8c2013-11-12 06:45:549840 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079841 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369842
[email protected]49639fa2011-12-20 23:22:419843 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369844
tfarina42834112016-09-22 13:38:209845 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369847
9848 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019849 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369850
[email protected]dd3aa792013-07-16 19:10:239851 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369852}
9853
bncd16676a2016-07-20 16:23:019854TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039855 class FakeUploadElementReader : public UploadElementReader {
9856 public:
9857 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209858 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039859
9860 const CompletionCallback& callback() const { return callback_; }
9861
9862 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209863 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039864 callback_ = callback;
9865 return ERR_IO_PENDING;
9866 }
avibf0746c2015-12-09 19:53:149867 uint64_t GetContentLength() const override { return 0; }
9868 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209869 int Read(IOBuffer* buf,
9870 int buf_length,
9871 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039872 return ERR_FAILED;
9873 }
9874
9875 private:
9876 CompletionCallback callback_;
9877 };
9878
9879 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099880 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9881 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229882 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039883
9884 HttpRequestInfo request;
9885 request.method = "POST";
bncce36dca22015-04-21 22:11:239886 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039887 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039888
danakj1fd259a02016-04-16 03:17:099889 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:589890 auto trans =
9891 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:039892
9893 StaticSocketDataProvider data;
9894 session_deps_.socket_factory->AddSocketDataProvider(&data);
9895
9896 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209897 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559899 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039900
9901 // Transaction is pending on request body initialization.
9902 ASSERT_FALSE(fake_reader->callback().is_null());
9903
9904 // Return Init()'s result after the transaction gets destroyed.
9905 trans.reset();
9906 fake_reader->callback().Run(OK); // Should not crash.
9907}
9908
[email protected]aeefc9e82010-02-19 16:18:279909// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019910TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279911 HttpRequestInfo request;
9912 request.method = "GET";
bncce36dca22015-04-21 22:11:239913 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279914
9915 // First transaction will request a resource and receive a Basic challenge
9916 // with realm="first_realm".
9917 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239918 MockWrite(
9919 "GET / HTTP/1.1\r\n"
9920 "Host: www.example.org\r\n"
9921 "Connection: keep-alive\r\n"
9922 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279923 };
9924 MockRead data_reads1[] = {
9925 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9926 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9927 "\r\n"),
9928 };
9929
bnc691fda62016-08-12 00:43:169930 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279931 // for first_realm. The server will reject and provide a challenge with
9932 // second_realm.
9933 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239934 MockWrite(
9935 "GET / HTTP/1.1\r\n"
9936 "Host: www.example.org\r\n"
9937 "Connection: keep-alive\r\n"
9938 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9939 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279940 };
9941 MockRead data_reads2[] = {
9942 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9943 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9944 "\r\n"),
9945 };
9946
9947 // This again fails, and goes back to first_realm. Make sure that the
9948 // entry is removed from cache.
9949 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239950 MockWrite(
9951 "GET / HTTP/1.1\r\n"
9952 "Host: www.example.org\r\n"
9953 "Connection: keep-alive\r\n"
9954 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9955 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279956 };
9957 MockRead data_reads3[] = {
9958 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9959 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9960 "\r\n"),
9961 };
9962
9963 // Try one last time (with the correct password) and get the resource.
9964 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239965 MockWrite(
9966 "GET / HTTP/1.1\r\n"
9967 "Host: www.example.org\r\n"
9968 "Connection: keep-alive\r\n"
9969 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9970 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279971 };
9972 MockRead data_reads4[] = {
9973 MockRead("HTTP/1.1 200 OK\r\n"
9974 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509975 "Content-Length: 5\r\n"
9976 "\r\n"
9977 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279978 };
9979
9980 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9981 data_writes1, arraysize(data_writes1));
9982 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9983 data_writes2, arraysize(data_writes2));
9984 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9985 data_writes3, arraysize(data_writes3));
9986 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9987 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079988 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9989 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9990 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9991 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279992
[email protected]49639fa2011-12-20 23:22:419993 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279994
danakj1fd259a02016-04-16 03:17:099995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169996 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509997
[email protected]aeefc9e82010-02-19 16:18:279998 // Issue the first request with Authorize headers. There should be a
9999 // password prompt for first_realm waiting to be filled in after the
10000 // transaction completes.
tfarina42834112016-09-22 13:38:2010001 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710003 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110004 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610005 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210006 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410007 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210008 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410009 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310010 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410011 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910012 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710013
10014 // Issue the second request with an incorrect password. There should be a
10015 // password prompt for second_realm waiting to be filled in after the
10016 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110017 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610018 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10019 callback2.callback());
robpercival214763f2016-07-01 23:27:0110020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710021 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110022 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610023 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210024 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410025 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210026 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410027 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310028 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410029 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910030 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710031
10032 // Issue the third request with another incorrect password. There should be
10033 // a password prompt for first_realm waiting to be filled in. If the password
10034 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10035 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110036 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610037 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10038 callback3.callback());
robpercival214763f2016-07-01 23:27:0110039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710040 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110041 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610042 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210043 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410044 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210045 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410046 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310047 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410048 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910049 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710050
10051 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110052 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610053 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10054 callback4.callback());
robpercival214763f2016-07-01 23:27:0110055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710056 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110057 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610058 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210059 ASSERT_TRUE(response);
10060 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710061}
10062
bncd16676a2016-07-20 16:23:0110063TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210064 MockRead data_reads[] = {
10065 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310066 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210067 MockRead("\r\n"),
10068 MockRead("hello world"),
10069 MockRead(SYNCHRONOUS, OK),
10070 };
10071
10072 HttpRequestInfo request;
10073 request.method = "GET";
bncb26024382016-06-29 02:39:4510074 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210075
10076 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210077 session_deps_.socket_factory->AddSocketDataProvider(&data);
10078
bncb26024382016-06-29 02:39:4510079 SSLSocketDataProvider ssl(ASYNC, OK);
10080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10081
bncc958faa2015-07-31 18:14:5210082 TestCompletionCallback callback;
10083
danakj1fd259a02016-04-16 03:17:0910084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210086
tfarina42834112016-09-22 13:38:2010087 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210089
bncb26024382016-06-29 02:39:4510090 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010091 HttpServerProperties* http_server_properties =
10092 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410093 EXPECT_TRUE(
10094 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210095
robpercival214763f2016-07-01 23:27:0110096 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210097
bnc691fda62016-08-12 00:43:1610098 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210099 ASSERT_TRUE(response);
10100 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210101 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10102 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210103 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210104
10105 std::string response_data;
bnc691fda62016-08-12 00:43:1610106 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210107 EXPECT_EQ("hello world", response_data);
10108
zhongyic4de03032017-05-19 04:07:3410109 AlternativeServiceInfoVector alternative_service_info_vector =
10110 http_server_properties->GetAlternativeServiceInfos(test_server);
10111 ASSERT_EQ(1u, alternative_service_info_vector.size());
10112 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10113 EXPECT_EQ(alternative_service,
10114 alternative_service_info_vector[0].alternative_service);
bncc958faa2015-07-31 18:14:5210115}
10116
bnce3dd56f2016-06-01 10:37:1110117// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110118TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110119 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110120 MockRead data_reads[] = {
10121 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310122 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110123 MockRead("\r\n"),
10124 MockRead("hello world"),
10125 MockRead(SYNCHRONOUS, OK),
10126 };
10127
10128 HttpRequestInfo request;
10129 request.method = "GET";
10130 request.url = GURL("http://www.example.org/");
10131 request.load_flags = 0;
10132
10133 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10134 session_deps_.socket_factory->AddSocketDataProvider(&data);
10135
10136 TestCompletionCallback callback;
10137
10138 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610139 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110140
10141 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010142 HttpServerProperties* http_server_properties =
10143 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410144 EXPECT_TRUE(
10145 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110146
tfarina42834112016-09-22 13:38:2010147 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10149 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110150
bnc691fda62016-08-12 00:43:1610151 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110152 ASSERT_TRUE(response);
10153 ASSERT_TRUE(response->headers);
10154 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10155 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210156 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110157
10158 std::string response_data;
bnc691fda62016-08-12 00:43:1610159 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110160 EXPECT_EQ("hello world", response_data);
10161
zhongyic4de03032017-05-19 04:07:3410162 EXPECT_TRUE(
10163 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110164}
10165
bnca86731e2017-04-17 12:31:2810166// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510167// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110168TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510169 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810170 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510171
bnc8bef8da22016-05-30 01:28:2510172 HttpRequestInfo request;
10173 request.method = "GET";
bncb26024382016-06-29 02:39:4510174 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510175 request.load_flags = 0;
10176
10177 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10178 StaticSocketDataProvider first_data;
10179 first_data.set_connect_data(mock_connect);
10180 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510181 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610182 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510183 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510184
10185 MockRead data_reads[] = {
10186 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10187 MockRead(ASYNC, OK),
10188 };
10189 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10190 0);
10191 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10192
10193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10194
bnc525e175a2016-06-20 12:36:4010195 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510196 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110197 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10198 444);
bnc8bef8da22016-05-30 01:28:2510199 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10200 http_server_properties->SetAlternativeService(
10201 url::SchemeHostPort(request.url), alternative_service, expiration);
10202
bnc691fda62016-08-12 00:43:1610203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510204 TestCompletionCallback callback;
10205
tfarina42834112016-09-22 13:38:2010206 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510207 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110208 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510209}
10210
bnce3dd56f2016-06-01 10:37:1110211// Regression test for https://crbug.com/615497:
10212// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110213TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110214 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110215 HttpRequestInfo request;
10216 request.method = "GET";
10217 request.url = GURL("http://www.example.org/");
10218 request.load_flags = 0;
10219
10220 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10221 StaticSocketDataProvider first_data;
10222 first_data.set_connect_data(mock_connect);
10223 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10224
10225 MockRead data_reads[] = {
10226 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10227 MockRead(ASYNC, OK),
10228 };
10229 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10230 0);
10231 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10232
10233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10234
bnc525e175a2016-06-20 12:36:4010235 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110236 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110237 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110238 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10239 http_server_properties->SetAlternativeService(
10240 url::SchemeHostPort(request.url), alternative_service, expiration);
10241
bnc691fda62016-08-12 00:43:1610242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110243 TestCompletionCallback callback;
10244
tfarina42834112016-09-22 13:38:2010245 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110246 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110247 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110248}
10249
bncd16676a2016-07-20 16:23:0110250TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810251 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910252 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010253 HttpServerProperties* http_server_properties =
10254 session->http_server_properties();
bncb26024382016-06-29 02:39:4510255 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110256 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810257 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010258 http_server_properties->SetAlternativeService(
10259 test_server, alternative_service, expiration);
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,
10356 alternative_service_info_vector[0].alternative_service);
10357 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10358 1234);
10359 EXPECT_EQ(alternative_service_2,
10360 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);
zhongyi3d4a55e72016-04-22 20:36:4610401 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010402 expiration);
zhongyi48704c182015-12-07 07:52:0210403 // Mark the QUIC alternative service as broken.
10404 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10405
zhongyi48704c182015-12-07 07:52:0210406 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210408 request.method = "GET";
10409 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210410 TestCompletionCallback callback;
10411 NetErrorDetails details;
10412 EXPECT_FALSE(details.quic_broken);
10413
tfarina42834112016-09-22 13:38:2010414 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610415 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210416 EXPECT_TRUE(details.quic_broken);
10417}
10418
bncd16676a2016-07-20 16:23:0110419TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610420 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210421 HostPortPair alternative1("alternative1.example.org", 443);
10422 HostPortPair alternative2("alternative2.example.org", 443);
10423 std::string origin_url = "https://origin.example.org:443";
10424 std::string alternative_url1 = "https://alternative1.example.org:443";
10425 std::string alternative_url2 = "https://alternative2.example.org:443";
10426
10427 // Negotiate HTTP/1.1 with alternative1.example.org.
10428 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610429 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210430 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10431
10432 // HTTP/1.1 data for request.
10433 MockWrite http_writes[] = {
10434 MockWrite("GET / HTTP/1.1\r\n"
10435 "Host: alternative1.example.org\r\n"
10436 "Connection: keep-alive\r\n\r\n"),
10437 };
10438
10439 MockRead http_reads[] = {
10440 MockRead("HTTP/1.1 200 OK\r\n"
10441 "Content-Type: text/html; charset=iso-8859-1\r\n"
10442 "Content-Length: 40\r\n\r\n"
10443 "first HTTP/1.1 response from alternative1"),
10444 };
10445 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10446 http_writes, arraysize(http_writes));
10447 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10448
10449 StaticSocketDataProvider data_refused;
10450 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10451 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10452
danakj1fd259a02016-04-16 03:17:0910453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010454 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210455 session->http_server_properties();
10456
zhongyi3d4a55e72016-04-22 20:36:4610457 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210458 AlternativeServiceInfoVector alternative_service_info_vector;
10459 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10460
bnc3472afd2016-11-17 15:27:2110461 AlternativeService alternative_service1(kProtoQUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010462 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210463 expiration);
10464 alternative_service_info_vector.push_back(alternative_service_info1);
bnc3472afd2016-11-17 15:27:2110465 AlternativeService alternative_service2(kProtoQUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010466 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210467 expiration);
10468 alternative_service_info_vector.push_back(alternative_service_info2);
10469
10470 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610471 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210472
10473 // Mark one of the QUIC alternative service as broken.
10474 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410475 EXPECT_EQ(2u,
10476 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210477
zhongyi48704c182015-12-07 07:52:0210478 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610479 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210480 request.method = "GET";
10481 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210482 TestCompletionCallback callback;
10483 NetErrorDetails details;
10484 EXPECT_FALSE(details.quic_broken);
10485
tfarina42834112016-09-22 13:38:2010486 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610487 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210488 EXPECT_FALSE(details.quic_broken);
10489}
10490
bncd16676a2016-07-20 16:23:0110491TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210492 HttpRequestInfo request;
10493 request.method = "GET";
bncb26024382016-06-29 02:39:4510494 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210495
[email protected]d973e99a2012-02-17 21:02:3610496 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210497 StaticSocketDataProvider first_data;
10498 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710499 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510500 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610501 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210503
10504 MockRead data_reads[] = {
10505 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10506 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610507 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210508 };
10509 StaticSocketDataProvider second_data(
10510 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710511 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210512
danakj1fd259a02016-04-16 03:17:0910513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210514
bnc525e175a2016-06-20 12:36:4010515 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310516 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610517 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110518 // Port must be < 1024, or the header will be ignored (since initial port was
10519 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010520 const AlternativeService alternative_service(
bnc3472afd2016-11-17 15:27:2110521 kProtoHTTP2, "www.example.org",
bncd9b132e2015-07-08 05:16:1010522 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210523 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610524 http_server_properties->SetAlternativeService(server, alternative_service,
10525 expiration);
[email protected]564b4912010-03-09 16:30:4210526
bnc691fda62016-08-12 00:43:1610527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110528 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210529
tfarina42834112016-09-22 13:38:2010530 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10532 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210533
bnc691fda62016-08-12 00:43:1610534 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210535 ASSERT_TRUE(response);
10536 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210537 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10538
10539 std::string response_data;
bnc691fda62016-08-12 00:43:1610540 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210541 EXPECT_EQ("hello world", response_data);
10542
zhongyic4de03032017-05-19 04:07:3410543 const AlternativeServiceInfoVector alternative_service_info_vector =
10544 http_server_properties->GetAlternativeServiceInfos(server);
10545 ASSERT_EQ(1u, alternative_service_info_vector.size());
10546 EXPECT_EQ(alternative_service,
10547 alternative_service_info_vector[0].alternative_service);
10548 EXPECT_TRUE(
10549 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210550}
10551
bnc55ff9da2015-08-19 18:42:3510552// Ensure that we are not allowed to redirect traffic via an alternate protocol
10553// to an unrestricted (port >= 1024) when the original traffic was on a
10554// restricted port (port < 1024). Ensure that we can redirect in all other
10555// cases.
bncd16676a2016-07-20 16:23:0110556TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110557 HttpRequestInfo restricted_port_request;
10558 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510559 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110560 restricted_port_request.load_flags = 0;
10561
[email protected]d973e99a2012-02-17 21:02:3610562 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110563 StaticSocketDataProvider first_data;
10564 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710565 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110566
10567 MockRead data_reads[] = {
10568 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10569 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610570 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110571 };
10572 StaticSocketDataProvider second_data(
10573 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710574 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510575 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610576 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110578
danakj1fd259a02016-04-16 03:17:0910579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110580
bnc525e175a2016-06-20 12:36:4010581 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310582 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110583 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110584 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10585 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210586 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210587 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610588 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010589 expiration);
[email protected]3912662a32011-10-04 00:51:1110590
bnc691fda62016-08-12 00:43:1610591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110592 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110593
tfarina42834112016-09-22 13:38:2010594 int rv = trans.Start(&restricted_port_request, callback.callback(),
10595 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110597 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110598 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910599}
[email protected]3912662a32011-10-04 00:51:1110600
bnc55ff9da2015-08-19 18:42:3510601// Ensure that we are allowed to redirect traffic via an alternate protocol to
10602// an unrestricted (port >= 1024) when the original traffic was on a restricted
10603// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110604TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710605 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910606
10607 HttpRequestInfo restricted_port_request;
10608 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510609 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910610 restricted_port_request.load_flags = 0;
10611
10612 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10613 StaticSocketDataProvider first_data;
10614 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710615 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910616
10617 MockRead data_reads[] = {
10618 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10619 MockRead("hello world"),
10620 MockRead(ASYNC, OK),
10621 };
10622 StaticSocketDataProvider second_data(
10623 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710624 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510625 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610626 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910628
danakj1fd259a02016-04-16 03:17:0910629 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910630
bnc525e175a2016-06-20 12:36:4010631 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910632 session->http_server_properties();
10633 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110634 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10635 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210636 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210637 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610638 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010639 expiration);
[email protected]c54c6962013-02-01 04:53:1910640
bnc691fda62016-08-12 00:43:1610641 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910642 TestCompletionCallback callback;
10643
tfarina42834112016-09-22 13:38:2010644 EXPECT_EQ(ERR_IO_PENDING,
10645 trans.Start(&restricted_port_request, callback.callback(),
10646 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910647 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110648 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110649}
10650
bnc55ff9da2015-08-19 18:42:3510651// Ensure that we are not allowed to redirect traffic via an alternate protocol
10652// to an unrestricted (port >= 1024) when the original traffic was on a
10653// restricted port (port < 1024). Ensure that we can redirect in all other
10654// cases.
bncd16676a2016-07-20 16:23:0110655TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110656 HttpRequestInfo restricted_port_request;
10657 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510658 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110659 restricted_port_request.load_flags = 0;
10660
[email protected]d973e99a2012-02-17 21:02:3610661 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110662 StaticSocketDataProvider first_data;
10663 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710664 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110665
10666 MockRead data_reads[] = {
10667 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10668 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610669 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110670 };
10671 StaticSocketDataProvider second_data(
10672 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710673 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110674
bncb26024382016-06-29 02:39:4510675 SSLSocketDataProvider ssl(ASYNC, OK);
10676 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10677
danakj1fd259a02016-04-16 03:17:0910678 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110679
bnc525e175a2016-06-20 12:36:4010680 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310681 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110682 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110683 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10684 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210685 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210686 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610687 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010688 expiration);
[email protected]3912662a32011-10-04 00:51:1110689
bnc691fda62016-08-12 00:43:1610690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110691 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110692
tfarina42834112016-09-22 13:38:2010693 int rv = trans.Start(&restricted_port_request, callback.callback(),
10694 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110696 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110697 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110698}
10699
bnc55ff9da2015-08-19 18:42:3510700// Ensure that we are not allowed to redirect traffic via an alternate protocol
10701// to an unrestricted (port >= 1024) when the original traffic was on a
10702// restricted port (port < 1024). Ensure that we can redirect in all other
10703// cases.
bncd16676a2016-07-20 16:23:0110704TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110705 HttpRequestInfo unrestricted_port_request;
10706 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510707 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110708 unrestricted_port_request.load_flags = 0;
10709
[email protected]d973e99a2012-02-17 21:02:3610710 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110711 StaticSocketDataProvider first_data;
10712 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710713 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110714
10715 MockRead data_reads[] = {
10716 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10717 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610718 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110719 };
10720 StaticSocketDataProvider second_data(
10721 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710722 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510723 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610724 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110726
danakj1fd259a02016-04-16 03:17:0910727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110728
bnc525e175a2016-06-20 12:36:4010729 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310730 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110731 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110732 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10733 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210734 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210735 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610736 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010737 expiration);
[email protected]3912662a32011-10-04 00:51:1110738
bnc691fda62016-08-12 00:43:1610739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110740 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110741
bnc691fda62016-08-12 00:43:1610742 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010743 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110745 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110746 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110747}
10748
bnc55ff9da2015-08-19 18:42:3510749// Ensure that we are not allowed to redirect traffic via an alternate protocol
10750// to an unrestricted (port >= 1024) when the original traffic was on a
10751// restricted port (port < 1024). Ensure that we can redirect in all other
10752// cases.
bncd16676a2016-07-20 16:23:0110753TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110754 HttpRequestInfo unrestricted_port_request;
10755 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510756 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110757 unrestricted_port_request.load_flags = 0;
10758
[email protected]d973e99a2012-02-17 21:02:3610759 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110760 StaticSocketDataProvider first_data;
10761 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710762 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110763
10764 MockRead data_reads[] = {
10765 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10766 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610767 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110768 };
10769 StaticSocketDataProvider second_data(
10770 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710771 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110772
bncb26024382016-06-29 02:39:4510773 SSLSocketDataProvider ssl(ASYNC, OK);
10774 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10775
danakj1fd259a02016-04-16 03:17:0910776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110777
bnc525e175a2016-06-20 12:36:4010778 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310779 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210780 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110781 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10782 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210783 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210784 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610785 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010786 expiration);
[email protected]3912662a32011-10-04 00:51:1110787
bnc691fda62016-08-12 00:43:1610788 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110789 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110790
bnc691fda62016-08-12 00:43:1610791 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010792 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110794 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110795 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110796}
10797
bnc55ff9da2015-08-19 18:42:3510798// Ensure that we are not allowed to redirect traffic via an alternate protocol
10799// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10800// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110801TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210802 HttpRequestInfo request;
10803 request.method = "GET";
bncce36dca22015-04-21 22:11:2310804 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210805
10806 // The alternate protocol request will error out before we attempt to connect,
10807 // so only the standard HTTP request will try to connect.
10808 MockRead data_reads[] = {
10809 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10810 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610811 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210812 };
10813 StaticSocketDataProvider data(
10814 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710815 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210816
danakj1fd259a02016-04-16 03:17:0910817 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210818
bnc525e175a2016-06-20 12:36:4010819 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210820 session->http_server_properties();
10821 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110822 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10823 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210824 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210825 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610826 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210827
bnc691fda62016-08-12 00:43:1610828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210829 TestCompletionCallback callback;
10830
tfarina42834112016-09-22 13:38:2010831 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210833 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110834 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210835
bnc691fda62016-08-12 00:43:1610836 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210837 ASSERT_TRUE(response);
10838 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210839 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10840
10841 std::string response_data;
bnc691fda62016-08-12 00:43:1610842 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210843 EXPECT_EQ("hello world", response_data);
10844}
10845
bncd16676a2016-07-20 16:23:0110846TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410847 HttpRequestInfo request;
10848 request.method = "GET";
bncb26024382016-06-29 02:39:4510849 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410850
10851 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210852 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310853 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210854 MockRead("\r\n"),
10855 MockRead("hello world"),
10856 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10857 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410858
10859 StaticSocketDataProvider first_transaction(
10860 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710861 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510862 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610863 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510864 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410865
bnc032658ba2016-09-26 18:17:1510866 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410867
bncdf80d44fd2016-07-15 20:27:4110868 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510869 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110870 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410871
bnc42331402016-07-25 13:36:1510872 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110873 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410874 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110875 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410876 };
10877
rch8e6c6c42015-05-01 14:05:1310878 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10879 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710880 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410881
[email protected]d973e99a2012-02-17 21:02:3610882 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510883 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10884 NULL, 0, NULL, 0);
10885 hanging_non_alternate_protocol_socket.set_connect_data(
10886 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710887 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510888 &hanging_non_alternate_protocol_socket);
10889
[email protected]49639fa2011-12-20 23:22:4110890 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410891
danakj1fd259a02016-04-16 03:17:0910892 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810893 auto trans =
10894 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410895
tfarina42834112016-09-22 13:38:2010896 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10898 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410899
10900 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210901 ASSERT_TRUE(response);
10902 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410903 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10904
10905 std::string response_data;
robpercival214763f2016-07-01 23:27:0110906 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410907 EXPECT_EQ("hello world", response_data);
10908
bnc87dcefc2017-05-25 12:47:5810909 trans =
10910 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410911
tfarina42834112016-09-22 13:38:2010912 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10914 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410915
10916 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210917 ASSERT_TRUE(response);
10918 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210919 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310920 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210921 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410922
robpercival214763f2016-07-01 23:27:0110923 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410924 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410925}
10926
bncd16676a2016-07-20 16:23:0110927TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510928 HttpRequestInfo request;
10929 request.method = "GET";
bncb26024382016-06-29 02:39:4510930 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510931
bncb26024382016-06-29 02:39:4510932 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510933 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210934 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310935 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210936 MockRead("\r\n"),
10937 MockRead("hello world"),
10938 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10939 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510940 };
10941
bncb26024382016-06-29 02:39:4510942 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10943 0);
10944 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510945
bncb26024382016-06-29 02:39:4510946 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10947 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10948
10949 // Second transaction starts an alternative and a non-alternative Job.
10950 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610951 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810952 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10953 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810954 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10955
10956 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10957 hanging_socket2.set_connect_data(never_finishing_connect);
10958 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510959
bncb26024382016-06-29 02:39:4510960 // Third transaction starts an alternative and a non-alternative job.
10961 // The non-alternative job hangs, but the alternative one succeeds.
10962 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110963 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510964 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110965 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510966 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510967 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110968 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510969 };
bnc42331402016-07-25 13:36:1510970 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110971 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510972 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110973 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510974 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110975 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10976 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310977 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510978 };
10979
rch8e6c6c42015-05-01 14:05:1310980 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10981 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710982 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510983
bnc032658ba2016-09-26 18:17:1510984 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510985
mmenkecc2298e2015-12-07 18:20:1810986 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10987 hanging_socket3.set_connect_data(never_finishing_connect);
10988 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510989
danakj1fd259a02016-04-16 03:17:0910990 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110991 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010992 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510993
tfarina42834112016-09-22 13:38:2010994 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10996 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510997
10998 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210999 ASSERT_TRUE(response);
11000 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511001 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11002
11003 std::string response_data;
robpercival214763f2016-07-01 23:27:0111004 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511005 EXPECT_EQ("hello world", response_data);
11006
[email protected]49639fa2011-12-20 23:22:4111007 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011008 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011009 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511011
[email protected]49639fa2011-12-20 23:22:4111012 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011013 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011014 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511016
robpercival214763f2016-07-01 23:27:0111017 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11018 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511019
11020 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211021 ASSERT_TRUE(response);
11022 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211023 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511024 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211025 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111026 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511027 EXPECT_EQ("hello!", response_data);
11028
11029 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211030 ASSERT_TRUE(response);
11031 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211032 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511033 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211034 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111035 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511036 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511037}
11038
bncd16676a2016-07-20 16:23:0111039TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511040 HttpRequestInfo request;
11041 request.method = "GET";
bncb26024382016-06-29 02:39:4511042 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511043
11044 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211045 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311046 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211047 MockRead("\r\n"),
11048 MockRead("hello world"),
11049 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11050 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511051 };
11052
11053 StaticSocketDataProvider first_transaction(
11054 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711055 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511056
[email protected]8ddf8322012-02-23 18:08:0611057 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511059
[email protected]d973e99a2012-02-17 21:02:3611060 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511061 StaticSocketDataProvider hanging_alternate_protocol_socket(
11062 NULL, 0, NULL, 0);
11063 hanging_alternate_protocol_socket.set_connect_data(
11064 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711065 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511066 &hanging_alternate_protocol_socket);
11067
bncb26024382016-06-29 02:39:4511068 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811069 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11070 NULL, 0);
11071 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511073
[email protected]49639fa2011-12-20 23:22:4111074 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511075
danakj1fd259a02016-04-16 03:17:0911076 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811077 auto trans =
11078 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511079
tfarina42834112016-09-22 13:38:2011080 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111081 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11082 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511083
11084 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211085 ASSERT_TRUE(response);
11086 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511087 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11088
11089 std::string response_data;
robpercival214763f2016-07-01 23:27:0111090 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511091 EXPECT_EQ("hello world", response_data);
11092
bnc87dcefc2017-05-25 12:47:5811093 trans =
11094 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511095
tfarina42834112016-09-22 13:38:2011096 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11098 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511099
11100 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211101 ASSERT_TRUE(response);
11102 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511103 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11104 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211105 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511106
robpercival214763f2016-07-01 23:27:0111107 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511108 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511109}
11110
[email protected]631f1322010-04-30 17:59:1111111class CapturingProxyResolver : public ProxyResolver {
11112 public:
sammce90c9212015-05-27 23:43:3511113 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011114 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111115
dchengb03027d2014-10-21 12:00:2011116 int GetProxyForURL(const GURL& url,
11117 ProxyInfo* results,
11118 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511119 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011120 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011121 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11122 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211123 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111124 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211125 return OK;
[email protected]631f1322010-04-30 17:59:1111126 }
11127
[email protected]24476402010-07-20 20:55:1711128 const std::vector<GURL>& resolved() const { return resolved_; }
11129
11130 private:
[email protected]631f1322010-04-30 17:59:1111131 std::vector<GURL> resolved_;
11132
11133 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11134};
11135
sammce64b2362015-04-29 03:50:2311136class CapturingProxyResolverFactory : public ProxyResolverFactory {
11137 public:
11138 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11139 : ProxyResolverFactory(false), resolver_(resolver) {}
11140
11141 int CreateProxyResolver(
11142 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911143 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311144 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911145 std::unique_ptr<Request>* request) override {
bnc87dcefc2017-05-25 12:47:5811146 *resolver = base::MakeUnique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311147 return OK;
11148 }
11149
11150 private:
11151 ProxyResolver* resolver_;
11152};
11153
bnc2e884782016-08-11 19:45:1911154// Test that proxy is resolved using the origin url,
11155// regardless of the alternative server.
11156TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11157 // Configure proxy to bypass www.example.org, which is the origin URL.
11158 ProxyConfig proxy_config;
11159 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11160 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11161 auto proxy_config_service =
11162 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11163
11164 CapturingProxyResolver capturing_proxy_resolver;
11165 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11166 &capturing_proxy_resolver);
11167
11168 TestNetLog net_log;
11169
11170 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11171 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11172 &net_log);
11173
11174 session_deps_.net_log = &net_log;
11175
11176 // Configure alternative service with a hostname that is not bypassed by the
11177 // proxy.
11178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11179 HttpServerProperties* http_server_properties =
11180 session->http_server_properties();
11181 url::SchemeHostPort server("https", "www.example.org", 443);
11182 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111183 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911184 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11185 http_server_properties->SetAlternativeService(server, alternative_service,
11186 expiration);
11187
11188 // Non-alternative job should hang.
11189 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11190 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11191 nullptr, 0);
11192 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11193 session_deps_.socket_factory->AddSocketDataProvider(
11194 &hanging_alternate_protocol_socket);
11195
bnc032658ba2016-09-26 18:17:1511196 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911197
11198 HttpRequestInfo request;
11199 request.method = "GET";
11200 request.url = GURL("https://www.example.org/");
11201 request.load_flags = 0;
11202
11203 SpdySerializedFrame req(
11204 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11205
11206 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11207
11208 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11209 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11210 MockRead spdy_reads[] = {
11211 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11212 };
11213
11214 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11215 arraysize(spdy_writes));
11216 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11217
11218 TestCompletionCallback callback;
11219
11220 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11221
tfarina42834112016-09-22 13:38:2011222 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911223 EXPECT_THAT(callback.GetResult(rv), IsOk());
11224
11225 const HttpResponseInfo* response = trans.GetResponseInfo();
11226 ASSERT_TRUE(response);
11227 ASSERT_TRUE(response->headers);
11228 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11229 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211230 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911231
11232 std::string response_data;
11233 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11234 EXPECT_EQ("hello!", response_data);
11235
11236 // Origin host bypasses proxy, no resolution should have happened.
11237 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11238}
11239
bncd16676a2016-07-20 16:23:0111240TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111241 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211242 proxy_config.set_auto_detect(true);
11243 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111244
sammc5dd160c2015-04-02 02:43:1311245 CapturingProxyResolver capturing_proxy_resolver;
bnc87dcefc2017-05-25 12:47:5811246 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11247 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11248 base::MakeUnique<CapturingProxyResolverFactory>(
11249 &capturing_proxy_resolver),
11250 nullptr);
vishal.b62985ca92015-04-17 08:45:5111251 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711252 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111253
11254 HttpRequestInfo request;
11255 request.method = "GET";
bncb26024382016-06-29 02:39:4511256 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111257
11258 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211259 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311260 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211261 MockRead("\r\n"),
11262 MockRead("hello world"),
11263 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11264 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111265 };
11266
11267 StaticSocketDataProvider first_transaction(
11268 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711269 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511270 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611271 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511272 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111273
bnc032658ba2016-09-26 18:17:1511274 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111275
bncdf80d44fd2016-07-15 20:27:4111276 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511277 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111278 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311279 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511280 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11281 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311282 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111283 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111284 };
11285
[email protected]d911f1b2010-05-05 22:39:4211286 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11287
bnc42331402016-07-25 13:36:1511288 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111289 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111290 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111291 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11292 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111293 };
11294
rch8e6c6c42015-05-01 14:05:1311295 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11296 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711297 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111298
[email protected]d973e99a2012-02-17 21:02:3611299 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511300 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11301 NULL, 0, NULL, 0);
11302 hanging_non_alternate_protocol_socket.set_connect_data(
11303 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711304 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511305 &hanging_non_alternate_protocol_socket);
11306
[email protected]49639fa2011-12-20 23:22:4111307 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111308
danakj1fd259a02016-04-16 03:17:0911309 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811310 auto trans =
11311 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111312
tfarina42834112016-09-22 13:38:2011313 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111314 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11315 EXPECT_THAT(callback.WaitForResult(), IsOk());
11316
11317 const HttpResponseInfo* response = trans->GetResponseInfo();
11318 ASSERT_TRUE(response);
11319 ASSERT_TRUE(response->headers);
11320 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11321 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211322 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111323
11324 std::string response_data;
11325 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11326 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111327
bnc87dcefc2017-05-25 12:47:5811328 trans =
11329 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111330
tfarina42834112016-09-22 13:38:2011331 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11333 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111334
mmenkea2dcd3bf2016-08-16 21:49:4111335 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211336 ASSERT_TRUE(response);
11337 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211338 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311339 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211340 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111341
robpercival214763f2016-07-01 23:27:0111342 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111343 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511344 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11345 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311346 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311347 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311348 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111349
[email protected]029c83b62013-01-24 05:28:2011350 LoadTimingInfo load_timing_info;
11351 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11352 TestLoadTimingNotReusedWithPac(load_timing_info,
11353 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111354}
[email protected]631f1322010-04-30 17:59:1111355
bncd16676a2016-07-20 16:23:0111356TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811357 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411358 HttpRequestInfo request;
11359 request.method = "GET";
bncb26024382016-06-29 02:39:4511360 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411361
11362 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211363 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311364 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211365 MockRead("\r\n"),
11366 MockRead("hello world"),
11367 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411368 };
11369
11370 StaticSocketDataProvider first_transaction(
11371 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711372 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511373 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611374 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511375 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411376
bnc032658ba2016-09-26 18:17:1511377 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411378
bncdf80d44fd2016-07-15 20:27:4111379 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511380 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111381 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411382
bnc42331402016-07-25 13:36:1511383 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111384 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411385 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111386 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411387 };
11388
rch8e6c6c42015-05-01 14:05:1311389 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11390 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711391 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411392
[email protected]83039bb2011-12-09 18:43:5511393 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411394
danakj1fd259a02016-04-16 03:17:0911395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411396
bnc87dcefc2017-05-25 12:47:5811397 auto trans =
11398 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411399
tfarina42834112016-09-22 13:38:2011400 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111401 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11402 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411403
11404 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211405 ASSERT_TRUE(response);
11406 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411407 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11408
11409 std::string response_data;
robpercival214763f2016-07-01 23:27:0111410 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411411 EXPECT_EQ("hello world", response_data);
11412
11413 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511414 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011415 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311416 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711417 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011418 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811419
bnc87dcefc2017-05-25 12:47:5811420 trans =
11421 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411422
tfarina42834112016-09-22 13:38:2011423 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11425 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411426
11427 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211428 ASSERT_TRUE(response);
11429 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211430 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311431 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211432 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411433
robpercival214763f2016-07-01 23:27:0111434 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411435 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211436}
11437
[email protected]044de0642010-06-17 10:42:1511438// GenerateAuthToken is a mighty big test.
11439// It tests all permutation of GenerateAuthToken behavior:
11440// - Synchronous and Asynchronous completion.
11441// - OK or error on completion.
11442// - Direct connection, non-authenticating proxy, and authenticating proxy.
11443// - HTTP or HTTPS backend (to include proxy tunneling).
11444// - Non-authenticating and authenticating backend.
11445//
[email protected]fe3b7dc2012-02-03 19:52:0911446// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511447// problems generating an auth token for an authenticating proxy, we don't
11448// need to test all permutations of the backend server).
11449//
11450// The test proceeds by going over each of the configuration cases, and
11451// potentially running up to three rounds in each of the tests. The TestConfig
11452// specifies both the configuration for the test as well as the expectations
11453// for the results.
bncd16676a2016-07-20 16:23:0111454TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011455 static const char kServer[] = "http://www.example.com";
11456 static const char kSecureServer[] = "https://www.example.com";
11457 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511458
11459 enum AuthTiming {
11460 AUTH_NONE,
11461 AUTH_SYNC,
11462 AUTH_ASYNC,
11463 };
11464
11465 const MockWrite kGet(
11466 "GET / HTTP/1.1\r\n"
11467 "Host: www.example.com\r\n"
11468 "Connection: keep-alive\r\n\r\n");
11469 const MockWrite kGetProxy(
11470 "GET http://www.example.com/ HTTP/1.1\r\n"
11471 "Host: www.example.com\r\n"
11472 "Proxy-Connection: keep-alive\r\n\r\n");
11473 const MockWrite kGetAuth(
11474 "GET / HTTP/1.1\r\n"
11475 "Host: www.example.com\r\n"
11476 "Connection: keep-alive\r\n"
11477 "Authorization: auth_token\r\n\r\n");
11478 const MockWrite kGetProxyAuth(
11479 "GET http://www.example.com/ HTTP/1.1\r\n"
11480 "Host: www.example.com\r\n"
11481 "Proxy-Connection: keep-alive\r\n"
11482 "Proxy-Authorization: auth_token\r\n\r\n");
11483 const MockWrite kGetAuthThroughProxy(
11484 "GET http://www.example.com/ HTTP/1.1\r\n"
11485 "Host: www.example.com\r\n"
11486 "Proxy-Connection: keep-alive\r\n"
11487 "Authorization: auth_token\r\n\r\n");
11488 const MockWrite kGetAuthWithProxyAuth(
11489 "GET http://www.example.com/ HTTP/1.1\r\n"
11490 "Host: www.example.com\r\n"
11491 "Proxy-Connection: keep-alive\r\n"
11492 "Proxy-Authorization: auth_token\r\n"
11493 "Authorization: auth_token\r\n\r\n");
11494 const MockWrite kConnect(
11495 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711496 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511497 "Proxy-Connection: keep-alive\r\n\r\n");
11498 const MockWrite kConnectProxyAuth(
11499 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711500 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511501 "Proxy-Connection: keep-alive\r\n"
11502 "Proxy-Authorization: auth_token\r\n\r\n");
11503
11504 const MockRead kSuccess(
11505 "HTTP/1.1 200 OK\r\n"
11506 "Content-Type: text/html; charset=iso-8859-1\r\n"
11507 "Content-Length: 3\r\n\r\n"
11508 "Yes");
11509 const MockRead kFailure(
11510 "Should not be called.");
11511 const MockRead kServerChallenge(
11512 "HTTP/1.1 401 Unauthorized\r\n"
11513 "WWW-Authenticate: Mock realm=server\r\n"
11514 "Content-Type: text/html; charset=iso-8859-1\r\n"
11515 "Content-Length: 14\r\n\r\n"
11516 "Unauthorized\r\n");
11517 const MockRead kProxyChallenge(
11518 "HTTP/1.1 407 Unauthorized\r\n"
11519 "Proxy-Authenticate: Mock realm=proxy\r\n"
11520 "Proxy-Connection: close\r\n"
11521 "Content-Type: text/html; charset=iso-8859-1\r\n"
11522 "Content-Length: 14\r\n\r\n"
11523 "Unauthorized\r\n");
11524 const MockRead kProxyConnected(
11525 "HTTP/1.1 200 Connection Established\r\n\r\n");
11526
11527 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11528 // no constructors, but the C++ compiler on Windows warns about
11529 // unspecified data in compound literals. So, moved to using constructors,
11530 // and TestRound's created with the default constructor should not be used.
11531 struct TestRound {
11532 TestRound()
11533 : expected_rv(ERR_UNEXPECTED),
11534 extra_write(NULL),
11535 extra_read(NULL) {
11536 }
11537 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11538 int expected_rv_arg)
11539 : write(write_arg),
11540 read(read_arg),
11541 expected_rv(expected_rv_arg),
11542 extra_write(NULL),
11543 extra_read(NULL) {
11544 }
11545 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11546 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111547 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511548 : write(write_arg),
11549 read(read_arg),
11550 expected_rv(expected_rv_arg),
11551 extra_write(extra_write_arg),
11552 extra_read(extra_read_arg) {
11553 }
11554 MockWrite write;
11555 MockRead read;
11556 int expected_rv;
11557 const MockWrite* extra_write;
11558 const MockRead* extra_read;
11559 };
11560
11561 static const int kNoSSL = 500;
11562
11563 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111564 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111565 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511566 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111567 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111568 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511569 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111570 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511571 int num_auth_rounds;
11572 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611573 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511574 } test_configs[] = {
asankac93076192016-10-03 15:46:0211575 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111576 {__LINE__,
11577 nullptr,
asankac93076192016-10-03 15:46:0211578 AUTH_NONE,
11579 OK,
11580 kServer,
11581 AUTH_NONE,
11582 OK,
11583 1,
11584 kNoSSL,
11585 {TestRound(kGet, kSuccess, OK)}},
11586 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111587 {__LINE__,
11588 nullptr,
asankac93076192016-10-03 15:46:0211589 AUTH_NONE,
11590 OK,
11591 kServer,
11592 AUTH_SYNC,
11593 OK,
11594 2,
11595 kNoSSL,
11596 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511597 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111598 {__LINE__,
11599 nullptr,
asankac93076192016-10-03 15:46:0211600 AUTH_NONE,
11601 OK,
11602 kServer,
11603 AUTH_SYNC,
11604 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611605 3,
11606 kNoSSL,
11607 {TestRound(kGet, kServerChallenge, OK),
11608 TestRound(kGet, kServerChallenge, OK),
11609 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111610 {__LINE__,
11611 nullptr,
asankae2257db2016-10-11 22:03:1611612 AUTH_NONE,
11613 OK,
11614 kServer,
11615 AUTH_SYNC,
11616 ERR_UNSUPPORTED_AUTH_SCHEME,
11617 2,
11618 kNoSSL,
11619 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111620 {__LINE__,
11621 nullptr,
asankae2257db2016-10-11 22:03:1611622 AUTH_NONE,
11623 OK,
11624 kServer,
11625 AUTH_SYNC,
11626 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11627 2,
11628 kNoSSL,
11629 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111630 {__LINE__,
11631 kProxy,
asankae2257db2016-10-11 22:03:1611632 AUTH_SYNC,
11633 ERR_FAILED,
11634 kServer,
11635 AUTH_NONE,
11636 OK,
11637 2,
11638 kNoSSL,
11639 {TestRound(kGetProxy, kProxyChallenge, OK),
11640 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111641 {__LINE__,
11642 kProxy,
asankae2257db2016-10-11 22:03:1611643 AUTH_ASYNC,
11644 ERR_FAILED,
11645 kServer,
11646 AUTH_NONE,
11647 OK,
11648 2,
11649 kNoSSL,
11650 {TestRound(kGetProxy, kProxyChallenge, OK),
11651 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111652 {__LINE__,
11653 nullptr,
asankae2257db2016-10-11 22:03:1611654 AUTH_NONE,
11655 OK,
11656 kServer,
11657 AUTH_SYNC,
11658 ERR_FAILED,
asankac93076192016-10-03 15:46:0211659 2,
11660 kNoSSL,
11661 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611662 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111663 {__LINE__,
11664 nullptr,
asankae2257db2016-10-11 22:03:1611665 AUTH_NONE,
11666 OK,
11667 kServer,
11668 AUTH_ASYNC,
11669 ERR_FAILED,
11670 2,
11671 kNoSSL,
11672 {TestRound(kGet, kServerChallenge, OK),
11673 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111674 {__LINE__,
11675 nullptr,
asankac93076192016-10-03 15:46:0211676 AUTH_NONE,
11677 OK,
11678 kServer,
11679 AUTH_ASYNC,
11680 OK,
11681 2,
11682 kNoSSL,
11683 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511684 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111685 {__LINE__,
11686 nullptr,
asankac93076192016-10-03 15:46:0211687 AUTH_NONE,
11688 OK,
11689 kServer,
11690 AUTH_ASYNC,
11691 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611692 3,
asankac93076192016-10-03 15:46:0211693 kNoSSL,
11694 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611695 // The second round uses a HttpAuthHandlerMock that always succeeds.
11696 TestRound(kGet, kServerChallenge, OK),
11697 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211698 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111699 {__LINE__,
11700 kProxy,
asankac93076192016-10-03 15:46:0211701 AUTH_NONE,
11702 OK,
11703 kServer,
11704 AUTH_NONE,
11705 OK,
11706 1,
11707 kNoSSL,
11708 {TestRound(kGetProxy, kSuccess, OK)}},
11709 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111710 {__LINE__,
11711 kProxy,
asankac93076192016-10-03 15:46:0211712 AUTH_NONE,
11713 OK,
11714 kServer,
11715 AUTH_SYNC,
11716 OK,
11717 2,
11718 kNoSSL,
11719 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511720 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111721 {__LINE__,
11722 kProxy,
asankac93076192016-10-03 15:46:0211723 AUTH_NONE,
11724 OK,
11725 kServer,
11726 AUTH_SYNC,
11727 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611728 3,
asankac93076192016-10-03 15:46:0211729 kNoSSL,
11730 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611731 TestRound(kGetProxy, kServerChallenge, OK),
11732 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111733 {__LINE__,
11734 kProxy,
asankac93076192016-10-03 15:46:0211735 AUTH_NONE,
11736 OK,
11737 kServer,
11738 AUTH_ASYNC,
11739 OK,
11740 2,
11741 kNoSSL,
11742 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511743 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111744 {__LINE__,
11745 kProxy,
asankac93076192016-10-03 15:46:0211746 AUTH_NONE,
11747 OK,
11748 kServer,
11749 AUTH_ASYNC,
11750 ERR_INVALID_AUTH_CREDENTIALS,
11751 2,
11752 kNoSSL,
11753 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611754 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211755 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111756 {__LINE__,
11757 kProxy,
asankac93076192016-10-03 15:46:0211758 AUTH_SYNC,
11759 OK,
11760 kServer,
11761 AUTH_NONE,
11762 OK,
11763 2,
11764 kNoSSL,
11765 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511766 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111767 {__LINE__,
11768 kProxy,
asankac93076192016-10-03 15:46:0211769 AUTH_SYNC,
11770 ERR_INVALID_AUTH_CREDENTIALS,
11771 kServer,
11772 AUTH_NONE,
11773 OK,
11774 2,
11775 kNoSSL,
11776 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611777 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111778 {__LINE__,
11779 kProxy,
asankac93076192016-10-03 15:46:0211780 AUTH_ASYNC,
11781 OK,
11782 kServer,
11783 AUTH_NONE,
11784 OK,
11785 2,
11786 kNoSSL,
11787 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511788 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111789 {__LINE__,
11790 kProxy,
asankac93076192016-10-03 15:46:0211791 AUTH_ASYNC,
11792 ERR_INVALID_AUTH_CREDENTIALS,
11793 kServer,
11794 AUTH_NONE,
11795 OK,
11796 2,
11797 kNoSSL,
11798 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611799 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111800 {__LINE__,
11801 kProxy,
11802 AUTH_ASYNC,
11803 ERR_INVALID_AUTH_CREDENTIALS,
11804 kServer,
11805 AUTH_NONE,
11806 OK,
11807 3,
11808 kNoSSL,
11809 {TestRound(kGetProxy, kProxyChallenge, OK),
11810 TestRound(kGetProxy, kProxyChallenge, OK),
11811 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211812 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111813 {__LINE__,
11814 kProxy,
asankac93076192016-10-03 15:46:0211815 AUTH_SYNC,
11816 OK,
11817 kServer,
11818 AUTH_SYNC,
11819 OK,
11820 3,
11821 kNoSSL,
11822 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511823 TestRound(kGetProxyAuth, kServerChallenge, OK),
11824 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111825 {__LINE__,
11826 kProxy,
asankac93076192016-10-03 15:46:0211827 AUTH_SYNC,
11828 OK,
11829 kServer,
11830 AUTH_SYNC,
11831 ERR_INVALID_AUTH_CREDENTIALS,
11832 3,
11833 kNoSSL,
11834 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511835 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611836 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111837 {__LINE__,
11838 kProxy,
asankac93076192016-10-03 15:46:0211839 AUTH_ASYNC,
11840 OK,
11841 kServer,
11842 AUTH_SYNC,
11843 OK,
11844 3,
11845 kNoSSL,
11846 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511847 TestRound(kGetProxyAuth, kServerChallenge, OK),
11848 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111849 {__LINE__,
11850 kProxy,
asankac93076192016-10-03 15:46:0211851 AUTH_ASYNC,
11852 OK,
11853 kServer,
11854 AUTH_SYNC,
11855 ERR_INVALID_AUTH_CREDENTIALS,
11856 3,
11857 kNoSSL,
11858 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511859 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611860 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111861 {__LINE__,
11862 kProxy,
asankac93076192016-10-03 15:46:0211863 AUTH_SYNC,
11864 OK,
11865 kServer,
11866 AUTH_ASYNC,
11867 OK,
11868 3,
11869 kNoSSL,
11870 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511871 TestRound(kGetProxyAuth, kServerChallenge, OK),
11872 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111873 {__LINE__,
11874 kProxy,
11875 AUTH_SYNC,
11876 ERR_INVALID_AUTH_CREDENTIALS,
11877 kServer,
11878 AUTH_ASYNC,
11879 OK,
11880 4,
11881 kNoSSL,
11882 {TestRound(kGetProxy, kProxyChallenge, OK),
11883 TestRound(kGetProxy, kProxyChallenge, OK),
11884 TestRound(kGetProxyAuth, kServerChallenge, OK),
11885 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11886 {__LINE__,
11887 kProxy,
asankac93076192016-10-03 15:46:0211888 AUTH_SYNC,
11889 OK,
11890 kServer,
11891 AUTH_ASYNC,
11892 ERR_INVALID_AUTH_CREDENTIALS,
11893 3,
11894 kNoSSL,
11895 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511896 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611897 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111898 {__LINE__,
11899 kProxy,
asankac93076192016-10-03 15:46:0211900 AUTH_ASYNC,
11901 OK,
11902 kServer,
11903 AUTH_ASYNC,
11904 OK,
11905 3,
11906 kNoSSL,
11907 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511908 TestRound(kGetProxyAuth, kServerChallenge, OK),
11909 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111910 {__LINE__,
11911 kProxy,
asankac93076192016-10-03 15:46:0211912 AUTH_ASYNC,
11913 OK,
11914 kServer,
11915 AUTH_ASYNC,
11916 ERR_INVALID_AUTH_CREDENTIALS,
11917 3,
11918 kNoSSL,
11919 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511920 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611921 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111922 {__LINE__,
11923 kProxy,
11924 AUTH_ASYNC,
11925 ERR_INVALID_AUTH_CREDENTIALS,
11926 kServer,
11927 AUTH_ASYNC,
11928 ERR_INVALID_AUTH_CREDENTIALS,
11929 4,
11930 kNoSSL,
11931 {TestRound(kGetProxy, kProxyChallenge, OK),
11932 TestRound(kGetProxy, kProxyChallenge, OK),
11933 TestRound(kGetProxyAuth, kServerChallenge, OK),
11934 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211935 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111936 {__LINE__,
11937 nullptr,
asankac93076192016-10-03 15:46:0211938 AUTH_NONE,
11939 OK,
11940 kSecureServer,
11941 AUTH_NONE,
11942 OK,
11943 1,
11944 0,
11945 {TestRound(kGet, kSuccess, OK)}},
11946 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111947 {__LINE__,
11948 nullptr,
asankac93076192016-10-03 15:46:0211949 AUTH_NONE,
11950 OK,
11951 kSecureServer,
11952 AUTH_SYNC,
11953 OK,
11954 2,
11955 0,
11956 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511957 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111958 {__LINE__,
11959 nullptr,
asankac93076192016-10-03 15:46:0211960 AUTH_NONE,
11961 OK,
11962 kSecureServer,
11963 AUTH_SYNC,
11964 ERR_INVALID_AUTH_CREDENTIALS,
11965 2,
11966 0,
asankae2257db2016-10-11 22:03:1611967 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111968 {__LINE__,
11969 nullptr,
asankac93076192016-10-03 15:46:0211970 AUTH_NONE,
11971 OK,
11972 kSecureServer,
11973 AUTH_ASYNC,
11974 OK,
11975 2,
11976 0,
11977 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511978 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111979 {__LINE__,
11980 nullptr,
asankac93076192016-10-03 15:46:0211981 AUTH_NONE,
11982 OK,
11983 kSecureServer,
11984 AUTH_ASYNC,
11985 ERR_INVALID_AUTH_CREDENTIALS,
11986 2,
11987 0,
asankae2257db2016-10-11 22:03:1611988 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211989 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111990 {__LINE__,
11991 kProxy,
asankac93076192016-10-03 15:46:0211992 AUTH_NONE,
11993 OK,
11994 kSecureServer,
11995 AUTH_NONE,
11996 OK,
11997 1,
11998 0,
11999 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12000 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112001 {__LINE__,
12002 kProxy,
asankac93076192016-10-03 15:46:0212003 AUTH_NONE,
12004 OK,
12005 kSecureServer,
12006 AUTH_SYNC,
12007 OK,
12008 2,
12009 0,
12010 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512011 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112012 {__LINE__,
12013 kProxy,
asankac93076192016-10-03 15:46:0212014 AUTH_NONE,
12015 OK,
12016 kSecureServer,
12017 AUTH_SYNC,
12018 ERR_INVALID_AUTH_CREDENTIALS,
12019 2,
12020 0,
12021 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612022 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112023 {__LINE__,
12024 kProxy,
asankac93076192016-10-03 15:46:0212025 AUTH_NONE,
12026 OK,
12027 kSecureServer,
12028 AUTH_ASYNC,
12029 OK,
12030 2,
12031 0,
12032 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512033 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112034 {__LINE__,
12035 kProxy,
asankac93076192016-10-03 15:46:0212036 AUTH_NONE,
12037 OK,
12038 kSecureServer,
12039 AUTH_ASYNC,
12040 ERR_INVALID_AUTH_CREDENTIALS,
12041 2,
12042 0,
12043 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612044 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212045 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112046 {__LINE__,
12047 kProxy,
asankac93076192016-10-03 15:46:0212048 AUTH_SYNC,
12049 OK,
12050 kSecureServer,
12051 AUTH_NONE,
12052 OK,
12053 2,
12054 1,
12055 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512056 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112057 {__LINE__,
12058 kProxy,
asankac93076192016-10-03 15:46:0212059 AUTH_SYNC,
12060 ERR_INVALID_AUTH_CREDENTIALS,
12061 kSecureServer,
12062 AUTH_NONE,
12063 OK,
12064 2,
12065 kNoSSL,
12066 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612067 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112068 {__LINE__,
12069 kProxy,
asankae2257db2016-10-11 22:03:1612070 AUTH_SYNC,
12071 ERR_UNSUPPORTED_AUTH_SCHEME,
12072 kSecureServer,
12073 AUTH_NONE,
12074 OK,
12075 2,
12076 kNoSSL,
12077 {TestRound(kConnect, kProxyChallenge, OK),
12078 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112079 {__LINE__,
12080 kProxy,
asankae2257db2016-10-11 22:03:1612081 AUTH_SYNC,
12082 ERR_UNEXPECTED,
12083 kSecureServer,
12084 AUTH_NONE,
12085 OK,
12086 2,
12087 kNoSSL,
12088 {TestRound(kConnect, kProxyChallenge, OK),
12089 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112090 {__LINE__,
12091 kProxy,
asankac93076192016-10-03 15:46:0212092 AUTH_ASYNC,
12093 OK,
12094 kSecureServer,
12095 AUTH_NONE,
12096 OK,
12097 2,
12098 1,
12099 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512100 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112101 {__LINE__,
12102 kProxy,
asankac93076192016-10-03 15:46:0212103 AUTH_ASYNC,
12104 ERR_INVALID_AUTH_CREDENTIALS,
12105 kSecureServer,
12106 AUTH_NONE,
12107 OK,
12108 2,
12109 kNoSSL,
12110 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612111 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212112 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112113 {__LINE__,
12114 kProxy,
asankac93076192016-10-03 15:46:0212115 AUTH_SYNC,
12116 OK,
12117 kSecureServer,
12118 AUTH_SYNC,
12119 OK,
12120 3,
12121 1,
12122 {TestRound(kConnect, kProxyChallenge, OK),
12123 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12124 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512125 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112126 {__LINE__,
12127 kProxy,
asankac93076192016-10-03 15:46:0212128 AUTH_SYNC,
12129 OK,
12130 kSecureServer,
12131 AUTH_SYNC,
12132 ERR_INVALID_AUTH_CREDENTIALS,
12133 3,
12134 1,
12135 {TestRound(kConnect, kProxyChallenge, OK),
12136 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12137 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612138 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112139 {__LINE__,
12140 kProxy,
asankac93076192016-10-03 15:46:0212141 AUTH_ASYNC,
12142 OK,
12143 kSecureServer,
12144 AUTH_SYNC,
12145 OK,
12146 3,
12147 1,
12148 {TestRound(kConnect, kProxyChallenge, OK),
12149 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12150 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512151 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112152 {__LINE__,
12153 kProxy,
asankac93076192016-10-03 15:46:0212154 AUTH_ASYNC,
12155 OK,
12156 kSecureServer,
12157 AUTH_SYNC,
12158 ERR_INVALID_AUTH_CREDENTIALS,
12159 3,
12160 1,
12161 {TestRound(kConnect, kProxyChallenge, OK),
12162 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12163 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612164 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112165 {__LINE__,
12166 kProxy,
asankac93076192016-10-03 15:46:0212167 AUTH_SYNC,
12168 OK,
12169 kSecureServer,
12170 AUTH_ASYNC,
12171 OK,
12172 3,
12173 1,
12174 {TestRound(kConnect, kProxyChallenge, OK),
12175 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12176 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512177 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112178 {__LINE__,
12179 kProxy,
asankac93076192016-10-03 15:46:0212180 AUTH_SYNC,
12181 OK,
12182 kSecureServer,
12183 AUTH_ASYNC,
12184 ERR_INVALID_AUTH_CREDENTIALS,
12185 3,
12186 1,
12187 {TestRound(kConnect, kProxyChallenge, OK),
12188 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12189 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612190 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112191 {__LINE__,
12192 kProxy,
asankac93076192016-10-03 15:46:0212193 AUTH_ASYNC,
12194 OK,
12195 kSecureServer,
12196 AUTH_ASYNC,
12197 OK,
12198 3,
12199 1,
12200 {TestRound(kConnect, kProxyChallenge, OK),
12201 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12202 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512203 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112204 {__LINE__,
12205 kProxy,
asankac93076192016-10-03 15:46:0212206 AUTH_ASYNC,
12207 OK,
12208 kSecureServer,
12209 AUTH_ASYNC,
12210 ERR_INVALID_AUTH_CREDENTIALS,
12211 3,
12212 1,
12213 {TestRound(kConnect, kProxyChallenge, OK),
12214 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12215 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612216 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112217 {__LINE__,
12218 kProxy,
12219 AUTH_ASYNC,
12220 ERR_INVALID_AUTH_CREDENTIALS,
12221 kSecureServer,
12222 AUTH_ASYNC,
12223 ERR_INVALID_AUTH_CREDENTIALS,
12224 4,
12225 2,
12226 {TestRound(kConnect, kProxyChallenge, OK),
12227 TestRound(kConnect, kProxyChallenge, OK),
12228 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12229 &kServerChallenge),
12230 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512231 };
12232
asanka463ca4262016-11-16 02:34:3112233 for (const auto& test_config : test_configs) {
12234 SCOPED_TRACE(::testing::Message() << "Test config at "
12235 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812236 HttpAuthHandlerMock::Factory* auth_factory(
12237 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712238 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912239 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612240
12241 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512242 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112243 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812244 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12245 std::string auth_challenge = "Mock realm=proxy";
12246 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412247 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12248 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812249 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012250 empty_ssl_info, origin,
12251 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812252 auth_handler->SetGenerateExpectation(
12253 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112254 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812255 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12256 }
[email protected]044de0642010-06-17 10:42:1512257 }
12258 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012259 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512260 std::string auth_challenge = "Mock realm=server";
12261 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412262 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12263 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512264 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012265 empty_ssl_info, origin,
12266 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512267 auth_handler->SetGenerateExpectation(
12268 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112269 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812270 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612271
12272 // The second handler always succeeds. It should only be used where there
12273 // are multiple auth sessions for server auth in the same network
12274 // transaction using the same auth scheme.
12275 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12276 base::MakeUnique<HttpAuthHandlerMock>();
12277 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12278 empty_ssl_info, origin,
12279 NetLogWithSource());
12280 second_handler->SetGenerateExpectation(true, OK);
12281 auth_factory->AddMockHandler(second_handler.release(),
12282 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512283 }
12284 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312285 session_deps_.proxy_service =
12286 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512287 } else {
rdsmith82957ad2015-09-16 19:42:0312288 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512289 }
12290
12291 HttpRequestInfo request;
12292 request.method = "GET";
12293 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512294
danakj1fd259a02016-04-16 03:17:0912295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512296
rchcb68dc62015-05-21 04:45:3612297 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12298
12299 std::vector<std::vector<MockRead>> mock_reads(1);
12300 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512301 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212302 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512303 const TestRound& read_write_round = test_config.rounds[round];
12304
12305 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612306 mock_reads.back().push_back(read_write_round.read);
12307 mock_writes.back().push_back(read_write_round.write);
12308
12309 // kProxyChallenge uses Proxy-Connection: close which means that the
12310 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412311 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612312 mock_reads.push_back(std::vector<MockRead>());
12313 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512314 }
12315
rchcb68dc62015-05-21 04:45:3612316 if (read_write_round.extra_read) {
12317 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512318 }
rchcb68dc62015-05-21 04:45:3612319 if (read_write_round.extra_write) {
12320 mock_writes.back().push_back(*read_write_round.extra_write);
12321 }
[email protected]044de0642010-06-17 10:42:1512322
12323 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512324 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712325 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512326 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612327 }
[email protected]044de0642010-06-17 10:42:1512328
danakj1fd259a02016-04-16 03:17:0912329 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612330 for (size_t i = 0; i < mock_reads.size(); ++i) {
bnc87dcefc2017-05-25 12:47:5812331 data_providers.push_back(base::MakeUnique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412332 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812333 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612334 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212335 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612336 }
12337
mmenkecc2298e2015-12-07 18:20:1812338 // Transaction must be created after DataProviders, so it's destroyed before
12339 // they are as well.
12340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12341
rchcb68dc62015-05-21 04:45:3612342 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212343 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612344 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512345 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112346 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512347 int rv;
12348 if (round == 0) {
tfarina42834112016-09-22 13:38:2012349 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512350 } else {
[email protected]49639fa2011-12-20 23:22:4112351 rv = trans.RestartWithAuth(
12352 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512353 }
12354 if (rv == ERR_IO_PENDING)
12355 rv = callback.WaitForResult();
12356
12357 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612358 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012359 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512360 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512361 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12362 continue;
12363 }
12364 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212365 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512366 } else {
wezca1070932016-05-26 20:30:5212367 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612368 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512369 }
12370 }
[email protected]e5ae96a2010-04-14 20:12:4512371 }
12372}
12373
bncd16676a2016-07-20 16:23:0112374TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412375 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412376 HttpAuthHandlerMock::Factory* auth_factory(
12377 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712378 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312379 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712380 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12381 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412382
12383 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12384 auth_handler->set_connection_based(true);
12385 std::string auth_challenge = "Mock realm=server";
12386 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412387 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12388 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912389 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412390 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012391 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812392 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412393
[email protected]c871bce92010-07-15 21:51:1412394 int rv = OK;
12395 const HttpResponseInfo* response = NULL;
12396 HttpRequestInfo request;
12397 request.method = "GET";
12398 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712399
danakj1fd259a02016-04-16 03:17:0912400 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012401
12402 // Use a TCP Socket Pool with only one connection per group. This is used
12403 // to validate that the TCP socket is not released to the pool between
12404 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212405 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812406 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012407 50, // Max sockets for pool
12408 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112409 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12410 NULL, session_deps_.net_log);
bnc87dcefc2017-05-25 12:47:5812411 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212412 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812413 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012414
bnc691fda62016-08-12 00:43:1612415 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112416 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412417
12418 const MockWrite kGet(
12419 "GET / HTTP/1.1\r\n"
12420 "Host: www.example.com\r\n"
12421 "Connection: keep-alive\r\n\r\n");
12422 const MockWrite kGetAuth(
12423 "GET / HTTP/1.1\r\n"
12424 "Host: www.example.com\r\n"
12425 "Connection: keep-alive\r\n"
12426 "Authorization: auth_token\r\n\r\n");
12427
12428 const MockRead kServerChallenge(
12429 "HTTP/1.1 401 Unauthorized\r\n"
12430 "WWW-Authenticate: Mock realm=server\r\n"
12431 "Content-Type: text/html; charset=iso-8859-1\r\n"
12432 "Content-Length: 14\r\n\r\n"
12433 "Unauthorized\r\n");
12434 const MockRead kSuccess(
12435 "HTTP/1.1 200 OK\r\n"
12436 "Content-Type: text/html; charset=iso-8859-1\r\n"
12437 "Content-Length: 3\r\n\r\n"
12438 "Yes");
12439
12440 MockWrite writes[] = {
12441 // First round
12442 kGet,
12443 // Second round
12444 kGetAuth,
12445 // Third round
12446 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012447 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012448 kGetAuth,
12449 // Competing request
12450 kGet,
[email protected]c871bce92010-07-15 21:51:1412451 };
12452 MockRead reads[] = {
12453 // First round
12454 kServerChallenge,
12455 // Second round
12456 kServerChallenge,
12457 // Third round
[email protected]eca50e122010-09-11 14:03:3012458 kServerChallenge,
12459 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412460 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012461 // Competing response
12462 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412463 };
12464 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12465 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712466 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412467
thestig9d3bb0c2015-01-24 00:49:5112468 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012469
12470 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412471 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012472 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412473 if (rv == ERR_IO_PENDING)
12474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112475 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612476 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212477 ASSERT_TRUE(response);
12478 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812479 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112480 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12481 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412482
[email protected]7ef4cbbb2011-02-06 11:19:1012483 // In between rounds, another request comes in for the same domain.
12484 // It should not be able to grab the TCP socket that trans has already
12485 // claimed.
bnc691fda62016-08-12 00:43:1612486 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112487 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012488 rv = trans_compete.Start(&request, callback_compete.callback(),
12489 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112490 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012491 // callback_compete.WaitForResult at this point would stall forever,
12492 // since the HttpNetworkTransaction does not release the request back to
12493 // the pool until after authentication completes.
12494
12495 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412496 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612497 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412498 if (rv == ERR_IO_PENDING)
12499 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112500 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612501 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212502 ASSERT_TRUE(response);
12503 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812504 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112505 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12506 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412507
[email protected]7ef4cbbb2011-02-06 11:19:1012508 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412509 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612510 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412511 if (rv == ERR_IO_PENDING)
12512 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112513 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612514 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212515 ASSERT_TRUE(response);
12516 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812517 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112518 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12519 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012520
[email protected]7ef4cbbb2011-02-06 11:19:1012521 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012522 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612523 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012524 if (rv == ERR_IO_PENDING)
12525 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112526 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612527 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212528 ASSERT_TRUE(response);
12529 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812530 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012531
asanka463ca4262016-11-16 02:34:3112532 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12533 // auth handler should transition to a DONE state in concert with the remote
12534 // server. But that's not something we can test here with a mock handler.
12535 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12536 auth_handler->state());
12537
[email protected]7ef4cbbb2011-02-06 11:19:1012538 // Read the body since the fourth round was successful. This will also
12539 // release the socket back to the pool.
12540 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612541 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012542 if (rv == ERR_IO_PENDING)
12543 rv = callback.WaitForResult();
12544 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612545 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012546 EXPECT_EQ(0, rv);
12547 // There are still 0 idle sockets, since the trans_compete transaction
12548 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812549 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012550
12551 // The competing request can now finish. Wait for the headers and then
12552 // read the body.
12553 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112554 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612555 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012556 if (rv == ERR_IO_PENDING)
12557 rv = callback.WaitForResult();
12558 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612559 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012560 EXPECT_EQ(0, rv);
12561
12562 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812563 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412564}
12565
[email protected]65041fa2010-05-21 06:56:5312566// This tests the case that a request is issued via http instead of spdy after
12567// npn is negotiated.
bncd16676a2016-07-20 16:23:0112568TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312569 HttpRequestInfo request;
12570 request.method = "GET";
bncce36dca22015-04-21 22:11:2312571 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312572
12573 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312574 MockWrite(
12575 "GET / HTTP/1.1\r\n"
12576 "Host: www.example.org\r\n"
12577 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312578 };
12579
12580 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212581 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312582 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212583 MockRead("\r\n"),
12584 MockRead("hello world"),
12585 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312586 };
12587
[email protected]8ddf8322012-02-23 18:08:0612588 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612589 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312590
[email protected]bb88e1d32013-05-03 23:11:0712591 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312592
12593 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12594 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712595 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312596
[email protected]49639fa2011-12-20 23:22:4112597 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312598
danakj1fd259a02016-04-16 03:17:0912599 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312601
tfarina42834112016-09-22 13:38:2012602 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312603
robpercival214763f2016-07-01 23:27:0112604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12605 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312606
bnc691fda62016-08-12 00:43:1612607 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212608 ASSERT_TRUE(response);
12609 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312610 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12611
12612 std::string response_data;
bnc691fda62016-08-12 00:43:1612613 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312614 EXPECT_EQ("hello world", response_data);
12615
12616 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212617 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312618}
[email protected]26ef6582010-06-24 02:30:4712619
bnc55ff9da2015-08-19 18:42:3512620// Simulate the SSL handshake completing with an NPN negotiation followed by an
12621// immediate server closing of the socket.
12622// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112623TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712624 HttpRequestInfo request;
12625 request.method = "GET";
bncce36dca22015-04-21 22:11:2312626 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712627
[email protected]8ddf8322012-02-23 18:08:0612628 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612629 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712631
bncdf80d44fd2016-07-15 20:27:4112632 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912633 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112634 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712635
12636 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612637 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712638 };
12639
rch8e6c6c42015-05-01 14:05:1312640 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12641 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712642 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712643
[email protected]49639fa2011-12-20 23:22:4112644 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712645
danakj1fd259a02016-04-16 03:17:0912646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712648
tfarina42834112016-09-22 13:38:2012649 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12651 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712652}
[email protected]65d34382010-07-01 18:12:2612653
[email protected]795cbf82013-07-22 09:37:2712654// A subclass of HttpAuthHandlerMock that records the request URL when
12655// it gets it. This is needed since the auth handler may get destroyed
12656// before we get a chance to query it.
12657class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12658 public:
12659 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12660
dchengb03027d2014-10-21 12:00:2012661 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712662
12663 protected:
dchengb03027d2014-10-21 12:00:2012664 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12665 const HttpRequestInfo* request,
12666 const CompletionCallback& callback,
12667 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712668 *url_ = request->url;
12669 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12670 credentials, request, callback, auth_token);
12671 }
12672
12673 private:
12674 GURL* url_;
12675};
12676
[email protected]8e6441ca2010-08-19 05:56:3812677// Test that if we cancel the transaction as the connection is completing, that
12678// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112679TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812680 // Setup everything about the connection to complete synchronously, so that
12681 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12682 // for is the callback from the HttpStreamRequest.
12683 // Then cancel the transaction.
12684 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612685 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812686 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612687 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12688 MockRead(SYNCHRONOUS, "hello world"),
12689 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812690 };
12691
[email protected]8e6441ca2010-08-19 05:56:3812692 HttpRequestInfo request;
12693 request.method = "GET";
bncce36dca22015-04-21 22:11:2312694 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812695
[email protected]bb88e1d32013-05-03 23:11:0712696 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812698 auto trans =
12699 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2712700
[email protected]8e6441ca2010-08-19 05:56:3812701 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12702 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712703 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812704
[email protected]49639fa2011-12-20 23:22:4112705 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812706
vishal.b62985ca92015-04-17 08:45:5112707 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112708 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812710 trans.reset(); // Cancel the transaction here.
12711
fdoray92e35a72016-06-10 15:54:5512712 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012713}
12714
[email protected]ecab6e052014-05-16 14:58:1212715// Test that if a transaction is cancelled after receiving the headers, the
12716// stream is drained properly and added back to the socket pool. The main
12717// purpose of this test is to make sure that an HttpStreamParser can be read
12718// from after the HttpNetworkTransaction and the objects it owns have been
12719// deleted.
12720// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112721TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212722 MockRead data_reads[] = {
12723 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12724 MockRead(ASYNC, "Content-Length: 2\r\n"),
12725 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12726 MockRead(ASYNC, "1"),
12727 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12728 // HttpNetworkTransaction has been deleted.
12729 MockRead(ASYNC, "2"),
12730 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12731 };
12732 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12733 session_deps_.socket_factory->AddSocketDataProvider(&data);
12734
danakj1fd259a02016-04-16 03:17:0912735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212736
12737 {
12738 HttpRequestInfo request;
12739 request.method = "GET";
bncce36dca22015-04-21 22:11:2312740 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212741
dcheng48459ac22014-08-26 00:46:4112742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212743 TestCompletionCallback callback;
12744
tfarina42834112016-09-22 13:38:2012745 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212747 callback.WaitForResult();
12748
12749 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212750 ASSERT_TRUE(response);
12751 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212752 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12753
12754 // The transaction and HttpRequestInfo are deleted.
12755 }
12756
12757 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512758 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212759
12760 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112761 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212762}
12763
[email protected]76a505b2010-08-25 06:23:0012764// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112765TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312766 session_deps_.proxy_service =
12767 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112768 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712769 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012771
[email protected]76a505b2010-08-25 06:23:0012772 HttpRequestInfo request;
12773 request.method = "GET";
bncce36dca22015-04-21 22:11:2312774 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012775
12776 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312777 MockWrite(
12778 "GET http://www.example.org/ HTTP/1.1\r\n"
12779 "Host: www.example.org\r\n"
12780 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012781 };
12782
12783 MockRead data_reads1[] = {
12784 MockRead("HTTP/1.1 200 OK\r\n"),
12785 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12786 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612787 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012788 };
12789
12790 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12791 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712792 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012793
[email protected]49639fa2011-12-20 23:22:4112794 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012795
bnc691fda62016-08-12 00:43:1612796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912797 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612798 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912799 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12800 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012801
bnc691fda62016-08-12 00:43:1612802 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012804
12805 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112806 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012807
bnc691fda62016-08-12 00:43:1612808 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212809 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012810
12811 EXPECT_TRUE(response->headers->IsKeepAlive());
12812 EXPECT_EQ(200, response->headers->response_code());
12813 EXPECT_EQ(100, response->headers->GetContentLength());
12814 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712815 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12816 HostPortPair::FromString("myproxy:70")),
12817 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912818 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12819 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12820 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012821 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012822
12823 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612824 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012825 TestLoadTimingNotReusedWithPac(load_timing_info,
12826 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012827}
12828
12829// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112830TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312831 session_deps_.proxy_service =
12832 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112833 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712834 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912835 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012836
[email protected]76a505b2010-08-25 06:23:0012837 HttpRequestInfo request;
12838 request.method = "GET";
bncce36dca22015-04-21 22:11:2312839 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012840
12841 // Since we have proxy, should try to establish tunnel.
12842 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712843 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12844 "Host: www.example.org:443\r\n"
12845 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012846
rsleevidb16bb02015-11-12 23:47:1712847 MockWrite("GET / HTTP/1.1\r\n"
12848 "Host: www.example.org\r\n"
12849 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012850 };
12851
12852 MockRead data_reads1[] = {
12853 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12854
12855 MockRead("HTTP/1.1 200 OK\r\n"),
12856 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12857 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612858 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012859 };
12860
12861 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12862 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712863 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612864 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012866
[email protected]49639fa2011-12-20 23:22:4112867 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012868
bnc691fda62016-08-12 00:43:1612869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912870 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612871 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912872 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12873 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012874
bnc691fda62016-08-12 00:43:1612875 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012877
12878 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112879 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612880 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012881 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012882 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012883 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12884 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012885 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012886 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012887 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12888 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012889
bnc691fda62016-08-12 00:43:1612890 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212891 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012892
12893 EXPECT_TRUE(response->headers->IsKeepAlive());
12894 EXPECT_EQ(200, response->headers->response_code());
12895 EXPECT_EQ(100, response->headers->GetContentLength());
12896 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12897 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712898 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12899 HostPortPair::FromString("myproxy:70")),
12900 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912901 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12902 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12903 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012904
12905 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612906 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012907 TestLoadTimingNotReusedWithPac(load_timing_info,
12908 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012909}
12910
rsleevidb16bb02015-11-12 23:47:1712911// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12912// literal host.
bncd16676a2016-07-20 16:23:0112913TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712914 session_deps_.proxy_service =
12915 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12916 BoundTestNetLog log;
12917 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712919
12920 HttpRequestInfo request;
12921 request.method = "GET";
12922 request.url = GURL("https://[::1]:443/");
12923
12924 // Since we have proxy, should try to establish tunnel.
12925 MockWrite data_writes1[] = {
12926 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12927 "Host: [::1]:443\r\n"
12928 "Proxy-Connection: keep-alive\r\n\r\n"),
12929
12930 MockWrite("GET / HTTP/1.1\r\n"
12931 "Host: [::1]\r\n"
12932 "Connection: keep-alive\r\n\r\n"),
12933 };
12934
12935 MockRead data_reads1[] = {
12936 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12937
12938 MockRead("HTTP/1.1 200 OK\r\n"),
12939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12940 MockRead("Content-Length: 100\r\n\r\n"),
12941 MockRead(SYNCHRONOUS, OK),
12942 };
12943
12944 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12945 data_writes1, arraysize(data_writes1));
12946 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12947 SSLSocketDataProvider ssl(ASYNC, OK);
12948 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12949
12950 TestCompletionCallback callback1;
12951
bnc691fda62016-08-12 00:43:1612952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712953
bnc691fda62016-08-12 00:43:1612954 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712956
12957 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112958 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712959 TestNetLogEntry::List entries;
12960 log.GetEntries(&entries);
12961 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012962 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12963 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712964 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012965 entries, pos,
12966 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12967 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712968
bnc691fda62016-08-12 00:43:1612969 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212970 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712971
12972 EXPECT_TRUE(response->headers->IsKeepAlive());
12973 EXPECT_EQ(200, response->headers->response_code());
12974 EXPECT_EQ(100, response->headers->GetContentLength());
12975 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12976 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712977 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12978 HostPortPair::FromString("myproxy:70")),
12979 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712980
12981 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612982 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712983 TestLoadTimingNotReusedWithPac(load_timing_info,
12984 CONNECT_TIMING_HAS_SSL_TIMES);
12985}
12986
[email protected]76a505b2010-08-25 06:23:0012987// Test a basic HTTPS GET request through a proxy, but the server hangs up
12988// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112989TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312990 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112991 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712992 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012994
[email protected]76a505b2010-08-25 06:23:0012995 HttpRequestInfo request;
12996 request.method = "GET";
bncce36dca22015-04-21 22:11:2312997 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012998
12999 // Since we have proxy, should try to establish tunnel.
13000 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713001 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13002 "Host: www.example.org:443\r\n"
13003 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013004
rsleevidb16bb02015-11-12 23:47:1713005 MockWrite("GET / HTTP/1.1\r\n"
13006 "Host: www.example.org\r\n"
13007 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013008 };
13009
13010 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613011 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013012 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613013 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013014 };
13015
13016 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13017 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713018 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613019 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713020 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013021
[email protected]49639fa2011-12-20 23:22:4113022 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013023
bnc691fda62016-08-12 00:43:1613024 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013025
bnc691fda62016-08-12 00:43:1613026 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013028
13029 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113030 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613031 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013032 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013033 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013034 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13035 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013036 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013037 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013038 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13039 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013040}
13041
[email protected]749eefa82010-09-13 22:14:0313042// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113043TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113044 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913045 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113046 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313047
bnc42331402016-07-25 13:36:1513048 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113049 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313050 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113051 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313052 };
13053
rch8e6c6c42015-05-01 14:05:1313054 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13055 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713056 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313057
[email protected]8ddf8322012-02-23 18:08:0613058 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613059 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713060 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313061
danakj1fd259a02016-04-16 03:17:0913062 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313063
13064 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313065 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013066 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313067 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713068 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513069 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313070
13071 HttpRequestInfo request;
13072 request.method = "GET";
bncce36dca22015-04-21 22:11:2313073 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313074
13075 // This is the important line that marks this as a preconnect.
13076 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13077
bnc691fda62016-08-12 00:43:1613078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313079
[email protected]41d64e82013-07-03 22:44:2613080 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013081 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113082 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13083 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313084}
13085
[email protected]73b8dd222010-11-11 19:55:2413086// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613087// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213088void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713089 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913090 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713091 request_info.url = GURL("https://www.example.com/");
13092 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913093 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713094
[email protected]8ddf8322012-02-23 18:08:0613095 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913096 MockWrite data_writes[] = {
13097 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413098 };
ttuttle859dc7a2015-04-23 19:42:2913099 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713100 session_deps_.socket_factory->AddSocketDataProvider(&data);
13101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413102
danakj1fd259a02016-04-16 03:17:0913103 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613104 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413105
[email protected]49639fa2011-12-20 23:22:4113106 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013107 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913108 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413109 rv = callback.WaitForResult();
13110 ASSERT_EQ(error, rv);
13111}
13112
bncd16676a2016-07-20 16:23:0113113TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413114 // Just check a grab bag of cert errors.
13115 static const int kErrors[] = {
13116 ERR_CERT_COMMON_NAME_INVALID,
13117 ERR_CERT_AUTHORITY_INVALID,
13118 ERR_CERT_DATE_INVALID,
13119 };
13120 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613121 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13122 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413123 }
13124}
13125
[email protected]bd0b6772011-01-11 19:59:3013126// Ensure that a client certificate is removed from the SSL client auth
13127// cache when:
13128// 1) No proxy is involved.
13129// 2) TLS False Start is disabled.
13130// 3) The initial TLS handshake requests a client certificate.
13131// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113132TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913133 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713134 request_info.url = GURL("https://www.example.com/");
13135 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913136 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713137
[email protected]bd0b6772011-01-11 19:59:3013138 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113139 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013140
13141 // [ssl_]data1 contains the data for the first SSL handshake. When a
13142 // CertificateRequest is received for the first time, the handshake will
13143 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913144 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013145 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913147 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713148 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013149
13150 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13151 // False Start is not being used, the result of the SSL handshake will be
13152 // returned as part of the SSLClientSocket::Connect() call. This test
13153 // matches the result of a server sending a handshake_failure alert,
13154 // rather than a Finished message, because it requires a client
13155 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913156 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013157 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713158 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913159 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713160 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013161
13162 // [ssl_]data3 contains the data for the third SSL handshake. When a
13163 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213164 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13165 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013166 // of the HttpNetworkTransaction. Because this test failure is due to
13167 // requiring a client certificate, this fallback handshake should also
13168 // fail.
ttuttle859dc7a2015-04-23 19:42:2913169 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013170 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713171 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913172 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713173 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013174
[email protected]80c75f682012-05-26 16:22:1713175 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13176 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213177 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13178 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713179 // of the HttpNetworkTransaction. Because this test failure is due to
13180 // requiring a client certificate, this fallback handshake should also
13181 // fail.
ttuttle859dc7a2015-04-23 19:42:2913182 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713183 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913185 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713186 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713187
danakj1fd259a02016-04-16 03:17:0913188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613189 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013190
[email protected]bd0b6772011-01-11 19:59:3013191 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113192 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013193 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113194 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013195
13196 // Complete the SSL handshake, which should abort due to requiring a
13197 // client certificate.
13198 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113199 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013200
13201 // Indicate that no certificate should be supplied. From the perspective
13202 // of SSLClientCertCache, NULL is just as meaningful as a real
13203 // certificate, so this is the same as supply a
13204 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613205 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113206 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013207
13208 // Ensure the certificate was added to the client auth cache before
13209 // allowing the connection to continue restarting.
13210 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413211 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113212 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413213 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213214 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013215
13216 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713217 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13218 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013219 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113220 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013221
13222 // Ensure that the client certificate is removed from the cache on a
13223 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113224 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413225 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013226}
13227
13228// Ensure that a client certificate is removed from the SSL client auth
13229// cache when:
13230// 1) No proxy is involved.
13231// 2) TLS False Start is enabled.
13232// 3) The initial TLS handshake requests a client certificate.
13233// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113234TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913235 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713236 request_info.url = GURL("https://www.example.com/");
13237 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913238 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713239
[email protected]bd0b6772011-01-11 19:59:3013240 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113241 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013242
13243 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13244 // return successfully after reading up to the peer's Certificate message.
13245 // This is to allow the caller to call SSLClientSocket::Write(), which can
13246 // enqueue application data to be sent in the same packet as the
13247 // ChangeCipherSpec and Finished messages.
13248 // The actual handshake will be finished when SSLClientSocket::Read() is
13249 // called, which expects to process the peer's ChangeCipherSpec and
13250 // Finished messages. If there was an error negotiating with the peer,
13251 // such as due to the peer requiring a client certificate when none was
13252 // supplied, the alert sent by the peer won't be processed until Read() is
13253 // called.
13254
13255 // Like the non-False Start case, when a client certificate is requested by
13256 // the peer, the handshake is aborted during the Connect() call.
13257 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913258 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013259 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713260 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913261 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713262 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013263
13264 // When a client certificate is supplied, Connect() will not be aborted
13265 // when the peer requests the certificate. Instead, the handshake will
13266 // artificially succeed, allowing the caller to write the HTTP request to
13267 // the socket. The handshake messages are not processed until Read() is
13268 // called, which then detects that the handshake was aborted, due to the
13269 // peer sending a handshake_failure because it requires a client
13270 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913271 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013272 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913274 MockRead data2_reads[] = {
13275 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013276 };
ttuttle859dc7a2015-04-23 19:42:2913277 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713278 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013279
13280 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713281 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13282 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913283 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013284 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913286 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713287 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013288
[email protected]80c75f682012-05-26 16:22:1713289 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13290 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913291 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713292 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713293 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913294 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713295 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713296
[email protected]7799de12013-05-30 05:52:5113297 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913298 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113299 ssl_data5.cert_request_info = cert_request.get();
13300 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913301 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113302 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13303
danakj1fd259a02016-04-16 03:17:0913304 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613305 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013306
[email protected]bd0b6772011-01-11 19:59:3013307 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113308 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013309 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113310 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013311
13312 // Complete the SSL handshake, which should abort due to requiring a
13313 // client certificate.
13314 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113315 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013316
13317 // Indicate that no certificate should be supplied. From the perspective
13318 // of SSLClientCertCache, NULL is just as meaningful as a real
13319 // certificate, so this is the same as supply a
13320 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613321 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113322 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013323
13324 // Ensure the certificate was added to the client auth cache before
13325 // allowing the connection to continue restarting.
13326 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413327 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113328 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413329 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213330 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013331
[email protected]bd0b6772011-01-11 19:59:3013332 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713333 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13334 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013335 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113336 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013337
13338 // Ensure that the client certificate is removed from the cache on a
13339 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113340 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413341 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013342}
13343
[email protected]8c405132011-01-11 22:03:1813344// Ensure that a client certificate is removed from the SSL client auth
13345// cache when:
13346// 1) An HTTPS proxy is involved.
13347// 3) The HTTPS proxy requests a client certificate.
13348// 4) The client supplies an invalid/unacceptable certificate for the
13349// proxy.
13350// The test is repeated twice, first for connecting to an HTTPS endpoint,
13351// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113352TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313353 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113354 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713355 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813356
13357 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113358 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813359
13360 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13361 // [ssl_]data[1-3]. Rather than represending the endpoint
13362 // (www.example.com:443), they represent failures with the HTTPS proxy
13363 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913364 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813365 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913367 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713368 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813369
ttuttle859dc7a2015-04-23 19:42:2913370 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813371 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913373 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713374 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813375
[email protected]80c75f682012-05-26 16:22:1713376 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13377#if 0
ttuttle859dc7a2015-04-23 19:42:2913378 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813379 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913381 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713382 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713383#endif
[email protected]8c405132011-01-11 22:03:1813384
ttuttle859dc7a2015-04-23 19:42:2913385 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813386 requests[0].url = GURL("https://www.example.com/");
13387 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913388 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813389
13390 requests[1].url = GURL("http://www.example.com/");
13391 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913392 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813393
13394 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713395 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913396 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613397 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813398
13399 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113400 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013401 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113402 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813403
13404 // Complete the SSL handshake, which should abort due to requiring a
13405 // client certificate.
13406 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113407 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813408
13409 // Indicate that no certificate should be supplied. From the perspective
13410 // of SSLClientCertCache, NULL is just as meaningful as a real
13411 // certificate, so this is the same as supply a
13412 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613413 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113414 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813415
13416 // Ensure the certificate was added to the client auth cache before
13417 // allowing the connection to continue restarting.
13418 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413419 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113420 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413421 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213422 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813423 // Ensure the certificate was NOT cached for the endpoint. This only
13424 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113425 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413426 HostPortPair("www.example.com", 443), &client_cert,
13427 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813428
13429 // Restart the handshake. This will consume ssl_data2, which fails, and
13430 // then consume ssl_data3, which should also fail. The result code is
13431 // checked against what ssl_data3 should return.
13432 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113433 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813434
13435 // Now that the new handshake has failed, ensure that the client
13436 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113437 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413438 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113439 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413440 HostPortPair("www.example.com", 443), &client_cert,
13441 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813442 }
13443}
13444
bncd16676a2016-07-20 16:23:0113445TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613446 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813447 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613449
bnc032658ba2016-09-26 18:17:1513450 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613451
bncdf80d44fd2016-07-15 20:27:4113452 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913453 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813454 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113455 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713456 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613457 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113458 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613459 };
bnc42331402016-07-25 13:36:1513460 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113461 SpdySerializedFrame host1_resp_body(
13462 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513463 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113464 SpdySerializedFrame host2_resp_body(
13465 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613466 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113467 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13468 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313469 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613470 };
13471
eroman36d84e54432016-03-17 03:23:0213472 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213473 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313474 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13475 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713476 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613477
[email protected]aa22b242011-11-16 18:58:2913478 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613479 HttpRequestInfo request1;
13480 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313481 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613482 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013483 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613484
tfarina42834112016-09-22 13:38:2013485 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13487 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613488
13489 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213490 ASSERT_TRUE(response);
13491 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213492 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613493
13494 std::string response_data;
robpercival214763f2016-07-01 23:27:0113495 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613496 EXPECT_EQ("hello!", response_data);
13497
bnca4d611d2016-09-22 19:55:3713498 // Preload mail.example.com into HostCache.
13499 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013500 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613501 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013502 std::unique_ptr<HostResolver::Request> request;
13503 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13504 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013505 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713507 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113508 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613509
13510 HttpRequestInfo request2;
13511 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713512 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613513 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013514 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613515
tfarina42834112016-09-22 13:38:2013516 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13518 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613519
13520 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213521 ASSERT_TRUE(response);
13522 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213523 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613524 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213525 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113526 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613527 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613528}
13529
bncd16676a2016-07-20 16:23:0113530TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213531 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813532 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213534
bnc032658ba2016-09-26 18:17:1513535 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213536
bncdf80d44fd2016-07-15 20:27:4113537 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913538 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813539 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113540 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713541 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213542 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113543 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213544 };
bnc42331402016-07-25 13:36:1513545 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113546 SpdySerializedFrame host1_resp_body(
13547 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513548 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113549 SpdySerializedFrame host2_resp_body(
13550 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213551 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113552 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13553 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313554 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213555 };
13556
eroman36d84e54432016-03-17 03:23:0213557 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213558 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313559 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13560 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713561 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213562
13563 TestCompletionCallback callback;
13564 HttpRequestInfo request1;
13565 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313566 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213567 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013568 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213569
tfarina42834112016-09-22 13:38:2013570 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13572 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213573
13574 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213575 ASSERT_TRUE(response);
13576 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213577 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213578
13579 std::string response_data;
robpercival214763f2016-07-01 23:27:0113580 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213581 EXPECT_EQ("hello!", response_data);
13582
13583 HttpRequestInfo request2;
13584 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713585 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213586 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013587 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213588
tfarina42834112016-09-22 13:38:2013589 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13591 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213592
13593 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213594 ASSERT_TRUE(response);
13595 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213596 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213597 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213598 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113599 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213600 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213601}
13602
bnc8016c1f2017-03-31 02:11:2913603// Regression test for https://crbug.com/546991.
13604// The server might not be able to serve an IP pooled request, and might send a
13605// 421 Misdirected Request response status to indicate this.
13606// HttpNetworkTransaction should reset the request and retry without IP pooling.
13607TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13608 // Two hosts resolve to the same IP address.
13609 const std::string ip_addr = "1.2.3.4";
13610 IPAddress ip;
13611 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13612 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13613
bnc87dcefc2017-05-25 12:47:5813614 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913615 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13616 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13617
13618 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13619
13620 // Two requests on the first connection.
13621 SpdySerializedFrame req1(
13622 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13623 spdy_util_.UpdateWithStreamDestruction(1);
13624 SpdySerializedFrame req2(
13625 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13626 SpdySerializedFrame rst(
13627 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13628 MockWrite writes1[] = {
13629 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13630 CreateMockWrite(rst, 6),
13631 };
13632
13633 // The first one succeeds, the second gets error 421 Misdirected Request.
13634 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13635 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13636 SpdyHeaderBlock response_headers;
13637 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13638 SpdySerializedFrame resp2(
13639 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13640 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13641 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13642
13643 MockConnect connect1(ASYNC, OK, peer_addr);
13644 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13645 arraysize(writes1));
13646 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13647
13648 AddSSLSocketData();
13649
13650 // Retry the second request on a second connection.
13651 SpdyTestUtil spdy_util2;
13652 SpdySerializedFrame req3(
13653 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13654 MockWrite writes2[] = {
13655 CreateMockWrite(req3, 0),
13656 };
13657
13658 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13659 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13660 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13661 MockRead(ASYNC, 0, 3)};
13662
13663 MockConnect connect2(ASYNC, OK, peer_addr);
13664 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13665 arraysize(writes2));
13666 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13667
13668 AddSSLSocketData();
13669
13670 // Preload mail.example.org into HostCache.
13671 HostPortPair host_port("mail.example.org", 443);
13672 HostResolver::RequestInfo resolve_info(host_port);
13673 AddressList ignored;
13674 std::unique_ptr<HostResolver::Request> request;
13675 TestCompletionCallback callback;
13676 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13677 &ignored, callback.callback(),
13678 &request, NetLogWithSource());
13679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13680 rv = callback.WaitForResult();
13681 EXPECT_THAT(rv, IsOk());
13682
13683 HttpRequestInfo request1;
13684 request1.method = "GET";
13685 request1.url = GURL("https://www.example.org/");
13686 request1.load_flags = 0;
13687 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13688
13689 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13691 rv = callback.WaitForResult();
13692 EXPECT_THAT(rv, IsOk());
13693
13694 const HttpResponseInfo* response = trans1.GetResponseInfo();
13695 ASSERT_TRUE(response);
13696 ASSERT_TRUE(response->headers);
13697 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13698 EXPECT_TRUE(response->was_fetched_via_spdy);
13699 EXPECT_TRUE(response->was_alpn_negotiated);
13700 std::string response_data;
13701 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13702 EXPECT_EQ("hello!", response_data);
13703
13704 HttpRequestInfo request2;
13705 request2.method = "GET";
13706 request2.url = GURL("https://mail.example.org/");
13707 request2.load_flags = 0;
13708 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13709
13710 BoundTestNetLog log;
13711 rv = trans2.Start(&request2, callback.callback(), log.bound());
13712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13713 rv = callback.WaitForResult();
13714 EXPECT_THAT(rv, IsOk());
13715
13716 response = trans2.GetResponseInfo();
13717 ASSERT_TRUE(response);
13718 ASSERT_TRUE(response->headers);
13719 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13720 EXPECT_TRUE(response->was_fetched_via_spdy);
13721 EXPECT_TRUE(response->was_alpn_negotiated);
13722 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13723 EXPECT_EQ("hello!", response_data);
13724
13725 TestNetLogEntry::List entries;
13726 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5913727 ExpectLogContainsSomewhere(
13728 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2913729 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5913730}
13731
13732// Test that HTTP 421 responses are properly returned to the caller if received
13733// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
13734// portions of the response.
13735TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
13736 // Two hosts resolve to the same IP address.
13737 const std::string ip_addr = "1.2.3.4";
13738 IPAddress ip;
13739 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13740 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13741
bnc87dcefc2017-05-25 12:47:5813742 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5913743 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13744 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13745
13746 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13747
13748 // Two requests on the first connection.
13749 SpdySerializedFrame req1(
13750 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13751 spdy_util_.UpdateWithStreamDestruction(1);
13752 SpdySerializedFrame req2(
13753 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13754 SpdySerializedFrame rst(
13755 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13756 MockWrite writes1[] = {
13757 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13758 CreateMockWrite(rst, 6),
13759 };
13760
13761 // The first one succeeds, the second gets error 421 Misdirected Request.
13762 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13763 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13764 SpdyHeaderBlock response_headers;
13765 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13766 SpdySerializedFrame resp2(
13767 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
13768 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13769 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13770
13771 MockConnect connect1(ASYNC, OK, peer_addr);
13772 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13773 arraysize(writes1));
13774 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13775
13776 AddSSLSocketData();
13777
13778 // Retry the second request on a second connection. It returns 421 Misdirected
13779 // Retry again.
13780 SpdyTestUtil spdy_util2;
13781 SpdySerializedFrame req3(
13782 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13783 MockWrite writes2[] = {
13784 CreateMockWrite(req3, 0),
13785 };
13786
13787 SpdySerializedFrame resp3(
13788 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
13789 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13790 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13791 MockRead(ASYNC, 0, 3)};
13792
13793 MockConnect connect2(ASYNC, OK, peer_addr);
13794 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13795 arraysize(writes2));
13796 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13797
13798 AddSSLSocketData();
13799
13800 // Preload mail.example.org into HostCache.
13801 HostPortPair host_port("mail.example.org", 443);
13802 HostResolver::RequestInfo resolve_info(host_port);
13803 AddressList ignored;
13804 std::unique_ptr<HostResolver::Request> request;
13805 TestCompletionCallback callback;
13806 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13807 &ignored, callback.callback(),
13808 &request, NetLogWithSource());
13809 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13810 rv = callback.WaitForResult();
13811 EXPECT_THAT(rv, IsOk());
13812
13813 HttpRequestInfo request1;
13814 request1.method = "GET";
13815 request1.url = GURL("https://www.example.org/");
13816 request1.load_flags = 0;
13817 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13818
13819 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13821 rv = callback.WaitForResult();
13822 EXPECT_THAT(rv, IsOk());
13823
13824 const HttpResponseInfo* response = trans1.GetResponseInfo();
13825 ASSERT_TRUE(response);
13826 ASSERT_TRUE(response->headers);
13827 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13828 EXPECT_TRUE(response->was_fetched_via_spdy);
13829 EXPECT_TRUE(response->was_alpn_negotiated);
13830 std::string response_data;
13831 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13832 EXPECT_EQ("hello!", response_data);
13833
13834 HttpRequestInfo request2;
13835 request2.method = "GET";
13836 request2.url = GURL("https://mail.example.org/");
13837 request2.load_flags = 0;
13838 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13839
13840 BoundTestNetLog log;
13841 rv = trans2.Start(&request2, callback.callback(), log.bound());
13842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13843 rv = callback.WaitForResult();
13844 EXPECT_THAT(rv, IsOk());
13845
13846 // After a retry, the 421 Misdirected Request is reported back up to the
13847 // caller.
13848 response = trans2.GetResponseInfo();
13849 ASSERT_TRUE(response);
13850 ASSERT_TRUE(response->headers);
13851 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
13852 EXPECT_TRUE(response->was_fetched_via_spdy);
13853 EXPECT_TRUE(response->was_alpn_negotiated);
13854 EXPECT_TRUE(response->ssl_info.cert);
13855 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13856 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2913857}
13858
bnc6dcd8192017-05-25 20:11:5013859class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4613860 public:
13861 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5013862 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013863 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613864
dchengb03027d2014-10-21 12:00:2013865 int ResolveFromCache(const RequestInfo& info,
13866 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013867 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5013868 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4013869 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5013870 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613871 return rv;
13872 }
13873
[email protected]e3ceb682011-06-28 23:55:4613874 private:
[email protected]e3ceb682011-06-28 23:55:4613875 const HostPortPair host_port_;
13876};
13877
bncd16676a2016-07-20 16:23:0113878TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313879 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613880 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnc6dcd8192017-05-25 20:11:5013881 session_deps_.host_resolver = base::MakeUnique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3713882 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0913883 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613884
bnc032658ba2016-09-26 18:17:1513885 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613886
bncdf80d44fd2016-07-15 20:27:4113887 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913888 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813889 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113890 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713891 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613892 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113893 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613894 };
bnc42331402016-07-25 13:36:1513895 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113896 SpdySerializedFrame host1_resp_body(
13897 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513898 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113899 SpdySerializedFrame host2_resp_body(
13900 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613901 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113902 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13903 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313904 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613905 };
13906
eroman36d84e54432016-03-17 03:23:0213907 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213908 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313909 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13910 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713911 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613912
[email protected]aa22b242011-11-16 18:58:2913913 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613914 HttpRequestInfo request1;
13915 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313916 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613917 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013918 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613919
tfarina42834112016-09-22 13:38:2013920 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13922 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613923
13924 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213925 ASSERT_TRUE(response);
13926 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213927 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613928
13929 std::string response_data;
robpercival214763f2016-07-01 23:27:0113930 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613931 EXPECT_EQ("hello!", response_data);
13932
13933 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713934 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613935 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013936 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5013937 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13938 &ignored, callback.callback(),
13939 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713941 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113942 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613943
13944 HttpRequestInfo request2;
13945 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713946 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613947 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013948 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613949
tfarina42834112016-09-22 13:38:2013950 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13952 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613953
13954 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213955 ASSERT_TRUE(response);
13956 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213957 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613958 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213959 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113960 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613961 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613962}
13963
bncd16676a2016-07-20 16:23:0113964TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313965 const std::string https_url = "https://www.example.org:8080/";
13966 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413967
13968 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113969 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913970 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413971
13972 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113973 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413974 };
13975
bnc42331402016-07-25 13:36:1513976 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113977 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13978 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913979 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413980
rch8e6c6c42015-05-01 14:05:1313981 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13982 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413983 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713984 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413985
13986 // HTTP GET for the HTTP URL
13987 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313988 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413989 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313990 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413991 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413992 };
13993
13994 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313995 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13996 MockRead(ASYNC, 2, "hello"),
13997 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413998 };
13999
rch8e6c6c42015-05-01 14:05:1314000 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14001 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414002
[email protected]8450d722012-07-02 19:14:0414003 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614004 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14006 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14007 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414008
danakj1fd259a02016-04-16 03:17:0914009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414010
14011 // Start the first transaction to set up the SpdySession
14012 HttpRequestInfo request1;
14013 request1.method = "GET";
14014 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414015 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014016 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414017 TestCompletionCallback callback1;
14018 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014019 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514020 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414021
robpercival214763f2016-07-01 23:27:0114022 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414023 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14024
14025 // Now, start the HTTP request
14026 HttpRequestInfo request2;
14027 request2.method = "GET";
14028 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414029 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014030 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414031 TestCompletionCallback callback2;
14032 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014033 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514034 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414035
robpercival214763f2016-07-01 23:27:0114036 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414037 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14038}
14039
bnc5452e2a2015-05-08 16:27:4214040// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14041// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114042TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514043 url::SchemeHostPort server("https", "www.example.org", 443);
14044 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214045
bnc8bef8da22016-05-30 01:28:2514046 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214047 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614048 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14050
14051 // No data should be read from the alternative, because HTTP/1.1 is
14052 // negotiated.
14053 StaticSocketDataProvider data;
14054 session_deps_.socket_factory->AddSocketDataProvider(&data);
14055
14056 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614057 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214058 // mocked. This way the request relies on the alternate Job.
14059 StaticSocketDataProvider data_refused;
14060 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14061 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14062
zhongyi3d4a55e72016-04-22 20:36:4614063 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014065 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214066 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114067 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214068 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614069 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014070 expiration);
bnc5452e2a2015-05-08 16:27:4214071
bnc5452e2a2015-05-08 16:27:4214072 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214074 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514075 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214076 TestCompletionCallback callback;
14077
14078 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214079 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014080 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214081 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214082}
14083
bnc40448a532015-05-11 19:13:1414084// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614085// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414086// succeeds, the request should succeed, even if the latter fails because
14087// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114088TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514089 url::SchemeHostPort server("https", "www.example.org", 443);
14090 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414091
14092 // Negotiate HTTP/1.1 with alternative.
14093 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614094 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414095 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14096
14097 // No data should be read from the alternative, because HTTP/1.1 is
14098 // negotiated.
14099 StaticSocketDataProvider data;
14100 session_deps_.socket_factory->AddSocketDataProvider(&data);
14101
zhongyi3d4a55e72016-04-22 20:36:4614102 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414103 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614104 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414105 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14106
14107 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514108 MockWrite("GET / HTTP/1.1\r\n"
14109 "Host: www.example.org\r\n"
14110 "Connection: keep-alive\r\n\r\n"),
14111 MockWrite("GET /second HTTP/1.1\r\n"
14112 "Host: www.example.org\r\n"
14113 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414114 };
14115
14116 MockRead http_reads[] = {
14117 MockRead("HTTP/1.1 200 OK\r\n"),
14118 MockRead("Content-Type: text/html\r\n"),
14119 MockRead("Content-Length: 6\r\n\r\n"),
14120 MockRead("foobar"),
14121 MockRead("HTTP/1.1 200 OK\r\n"),
14122 MockRead("Content-Type: text/html\r\n"),
14123 MockRead("Content-Length: 7\r\n\r\n"),
14124 MockRead("another"),
14125 };
14126 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14127 http_writes, arraysize(http_writes));
14128 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14129
zhongyi3d4a55e72016-04-22 20:36:4614130 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014132 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414133 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114134 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214135 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614136 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014137 expiration);
bnc40448a532015-05-11 19:13:1414138
14139 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14140 HttpRequestInfo request1;
14141 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514142 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414143 request1.load_flags = 0;
14144 TestCompletionCallback callback1;
14145
tfarina42834112016-09-22 13:38:2014146 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414147 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114148 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414149
14150 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214151 ASSERT_TRUE(response1);
14152 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414153 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14154
14155 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114156 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414157 EXPECT_EQ("foobar", response_data1);
14158
14159 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14160 // for alternative service.
14161 EXPECT_TRUE(
14162 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14163
zhongyi3d4a55e72016-04-22 20:36:4614164 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414165 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614166 // to server.
bnc40448a532015-05-11 19:13:1414167 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14168 HttpRequestInfo request2;
14169 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514170 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414171 request2.load_flags = 0;
14172 TestCompletionCallback callback2;
14173
tfarina42834112016-09-22 13:38:2014174 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414175 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114176 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414177
14178 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214179 ASSERT_TRUE(response2);
14180 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414181 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14182
14183 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114184 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414185 EXPECT_EQ("another", response_data2);
14186}
14187
bnc5452e2a2015-05-08 16:27:4214188// Alternative service requires HTTP/2 (or SPDY), but there is already a
14189// HTTP/1.1 socket open to the alternative server. That socket should not be
14190// used.
bncd16676a2016-07-20 16:23:0114191TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614192 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214193 HostPortPair alternative("alternative.example.org", 443);
14194 std::string origin_url = "https://origin.example.org:443";
14195 std::string alternative_url = "https://alternative.example.org:443";
14196
14197 // Negotiate HTTP/1.1 with alternative.example.org.
14198 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614199 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214200 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14201
14202 // HTTP/1.1 data for |request1| and |request2|.
14203 MockWrite http_writes[] = {
14204 MockWrite(
14205 "GET / HTTP/1.1\r\n"
14206 "Host: alternative.example.org\r\n"
14207 "Connection: keep-alive\r\n\r\n"),
14208 MockWrite(
14209 "GET / HTTP/1.1\r\n"
14210 "Host: alternative.example.org\r\n"
14211 "Connection: keep-alive\r\n\r\n"),
14212 };
14213
14214 MockRead http_reads[] = {
14215 MockRead(
14216 "HTTP/1.1 200 OK\r\n"
14217 "Content-Type: text/html; charset=iso-8859-1\r\n"
14218 "Content-Length: 40\r\n\r\n"
14219 "first HTTP/1.1 response from alternative"),
14220 MockRead(
14221 "HTTP/1.1 200 OK\r\n"
14222 "Content-Type: text/html; charset=iso-8859-1\r\n"
14223 "Content-Length: 41\r\n\r\n"
14224 "second HTTP/1.1 response from alternative"),
14225 };
14226 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14227 http_writes, arraysize(http_writes));
14228 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14229
14230 // This test documents that an alternate Job should not pool to an already
14231 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614232 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214233 StaticSocketDataProvider data_refused;
14234 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14235 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14236
zhongyi3d4a55e72016-04-22 20:36:4614237 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014239 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214240 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114241 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214242 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614243 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014244 expiration);
bnc5452e2a2015-05-08 16:27:4214245
14246 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214247 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614248 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214249 request1.method = "GET";
14250 request1.url = GURL(alternative_url);
14251 request1.load_flags = 0;
14252 TestCompletionCallback callback1;
14253
tfarina42834112016-09-22 13:38:2014254 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114255 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614256 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214257 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214258 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214259 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214260 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214261 EXPECT_FALSE(response1->was_fetched_via_spdy);
14262 std::string response_data1;
bnc691fda62016-08-12 00:43:1614263 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214264 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14265
14266 // Request for origin.example.org, which has an alternative service. This
14267 // will start two Jobs: the alternative looks for connections to pool to,
14268 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614269 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214270 // this request fails.
bnc5452e2a2015-05-08 16:27:4214271 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614272 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214273 request2.method = "GET";
14274 request2.url = GURL(origin_url);
14275 request2.load_flags = 0;
14276 TestCompletionCallback callback2;
14277
tfarina42834112016-09-22 13:38:2014278 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114279 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214280
14281 // Another transaction to alternative. This is to test that the HTTP/1.1
14282 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214283 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614284 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214285 request3.method = "GET";
14286 request3.url = GURL(alternative_url);
14287 request3.load_flags = 0;
14288 TestCompletionCallback callback3;
14289
tfarina42834112016-09-22 13:38:2014290 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114291 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614292 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214293 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214294 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214295 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214296 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214297 EXPECT_FALSE(response3->was_fetched_via_spdy);
14298 std::string response_data3;
bnc691fda62016-08-12 00:43:1614299 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214300 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14301}
14302
bncd16676a2016-07-20 16:23:0114303TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314304 const std::string https_url = "https://www.example.org:8080/";
14305 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414306
rdsmithebb50aa2015-11-12 03:44:3814307 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114308 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814309
[email protected]8450d722012-07-02 19:14:0414310 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314311 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114312 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414313 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114314 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914315 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114316 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214317 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914318
14319 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914320 SpdyHeaderBlock req2_block;
14321 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314322 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914323 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914324 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114325 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514326 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414327
14328 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114329 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14330 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414331 };
14332
bncdf80d44fd2016-07-15 20:27:4114333 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514334 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114335 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514336 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114337 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14338 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814339 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114340 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814341 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514342 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114343 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314344 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114345 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314346 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114347 CreateMockRead(wrapped_resp1, 4),
14348 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314349 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114350 CreateMockRead(resp2, 8),
14351 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314352 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14353 };
[email protected]8450d722012-07-02 19:14:0414354
mmenke666a6fea2015-12-19 04:16:3314355 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14356 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414357 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714358 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414359
rdsmith82957ad2015-09-16 19:42:0314360 session_deps_.proxy_service =
14361 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114362 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714363 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414364 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614365 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414367 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614368 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14370 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414371
danakj1fd259a02016-04-16 03:17:0914372 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414373
14374 // Start the first transaction to set up the SpdySession
14375 HttpRequestInfo request1;
14376 request1.method = "GET";
14377 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414378 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014379 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414380 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014381 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414382
mmenke666a6fea2015-12-19 04:16:3314383 // This pause is a hack to avoid running into https://crbug.com/497228.
14384 data1.RunUntilPaused();
14385 base::RunLoop().RunUntilIdle();
14386 data1.Resume();
robpercival214763f2016-07-01 23:27:0114387 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414388 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14389
[email protected]f6c63db52013-02-02 00:35:2214390 LoadTimingInfo load_timing_info1;
14391 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14392 TestLoadTimingNotReusedWithPac(load_timing_info1,
14393 CONNECT_TIMING_HAS_SSL_TIMES);
14394
mmenke666a6fea2015-12-19 04:16:3314395 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414396 HttpRequestInfo request2;
14397 request2.method = "GET";
14398 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414399 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014400 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414401 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014402 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414403
mmenke666a6fea2015-12-19 04:16:3314404 // This pause is a hack to avoid running into https://crbug.com/497228.
14405 data1.RunUntilPaused();
14406 base::RunLoop().RunUntilIdle();
14407 data1.Resume();
robpercival214763f2016-07-01 23:27:0114408 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314409
[email protected]8450d722012-07-02 19:14:0414410 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214411
14412 LoadTimingInfo load_timing_info2;
14413 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14414 // The established SPDY sessions is considered reused by the HTTP request.
14415 TestLoadTimingReusedWithPac(load_timing_info2);
14416 // HTTP requests over a SPDY session should have a different connection
14417 // socket_log_id than requests over a tunnel.
14418 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414419}
14420
[email protected]2d88e7d2012-07-19 17:55:1714421// Test that in the case where we have a SPDY session to a SPDY proxy
14422// that we do not pool other origins that resolve to the same IP when
14423// the certificate does not match the new origin.
14424// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114425TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314426 const std::string url1 = "http://www.example.org/";
14427 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714428 const std::string ip_addr = "1.2.3.4";
14429
rdsmithebb50aa2015-11-12 03:44:3814430 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114431 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814432
[email protected]2d88e7d2012-07-19 17:55:1714433 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614434 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314435 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114436 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514437 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714438
14439 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114440 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714441 };
14442
bnc42331402016-07-25 13:36:1514443 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114444 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714445 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114446 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14447 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714448 };
14449
mmenke666a6fea2015-12-19 04:16:3314450 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14451 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214452 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914453 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714454 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14455 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314456 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714457
14458 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114459 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914460 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714461
14462 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114463 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714464 };
14465
bnc42331402016-07-25 13:36:1514466 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114467 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14468 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314469 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714470
mmenke666a6fea2015-12-19 04:16:3314471 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14472 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714473 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314474 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714475
14476 // Set up a proxy config that sends HTTP requests to a proxy, and
14477 // all others direct.
14478 ProxyConfig proxy_config;
14479 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
bnc87dcefc2017-05-25 12:47:5814480 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
14481 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), nullptr,
14482 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714483
bncce36dca22015-04-21 22:11:2314484 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614485 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714486 // Load a valid cert. Note, that this does not need to
14487 // be valid for proxy because the MockSSLClientSocket does
14488 // not actually verify it. But SpdySession will use this
14489 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314490 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214491 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14493 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714494
14495 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614496 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314497 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14498 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714499
bnc87dcefc2017-05-25 12:47:5814500 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314501 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714502 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714503
danakj1fd259a02016-04-16 03:17:0914504 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714505
14506 // Start the first transaction to set up the SpdySession
14507 HttpRequestInfo request1;
14508 request1.method = "GET";
14509 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714510 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014511 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714512 TestCompletionCallback callback1;
14513 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014514 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314515 // This pause is a hack to avoid running into https://crbug.com/497228.
14516 data1.RunUntilPaused();
14517 base::RunLoop().RunUntilIdle();
14518 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714519
robpercival214763f2016-07-01 23:27:0114520 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714521 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14522
14523 // Now, start the HTTP request
14524 HttpRequestInfo request2;
14525 request2.method = "GET";
14526 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714527 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014528 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714529 TestCompletionCallback callback2;
14530 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014531 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514532 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714533
14534 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114535 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714536 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14537}
14538
[email protected]85f97342013-04-17 06:12:2414539// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14540// error) in SPDY session, removes the socket from pool and closes the SPDY
14541// session. Verify that new url's from the same HttpNetworkSession (and a new
14542// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114543TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314544 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414545
14546 MockRead reads1[] = {
14547 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14548 };
14549
mmenke11eb5152015-06-09 14:50:5014550 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414551
bncdf80d44fd2016-07-15 20:27:4114552 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914553 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414554 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114555 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414556 };
14557
bnc42331402016-07-25 13:36:1514558 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114559 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414560 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114561 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14562 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414563 };
14564
mmenke11eb5152015-06-09 14:50:5014565 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14566 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414567
[email protected]85f97342013-04-17 06:12:2414568 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614569 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014570 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14571 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414572
14573 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614574 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014575 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14576 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414577
danakj1fd259a02016-04-16 03:17:0914578 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014579 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414580
14581 // Start the first transaction to set up the SpdySession and verify that
14582 // connection was closed.
14583 HttpRequestInfo request1;
14584 request1.method = "GET";
14585 request1.url = GURL(https_url);
14586 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014587 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414588 TestCompletionCallback callback1;
14589 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014590 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114591 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414592
14593 // Now, start the second request and make sure it succeeds.
14594 HttpRequestInfo request2;
14595 request2.method = "GET";
14596 request2.url = GURL(https_url);
14597 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014598 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414599 TestCompletionCallback callback2;
14600 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014601 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414602
robpercival214763f2016-07-01 23:27:0114603 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414604 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14605}
14606
bncd16676a2016-07-20 16:23:0114607TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314608 ClientSocketPoolManager::set_max_sockets_per_group(
14609 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14610 ClientSocketPoolManager::set_max_sockets_per_pool(
14611 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14612
14613 // Use two different hosts with different IPs so they don't get pooled.
14614 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14615 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314617
14618 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614619 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314620 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614621 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14624
bncdf80d44fd2016-07-15 20:27:4114625 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914626 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314627 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114628 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314629 };
bnc42331402016-07-25 13:36:1514630 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114631 SpdySerializedFrame host1_resp_body(
14632 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314633 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114634 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914635 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314636 };
14637
rdsmithebb50aa2015-11-12 03:44:3814638 // Use a separate test instance for the separate SpdySession that will be
14639 // created.
bncd16676a2016-07-20 16:23:0114640 SpdyTestUtil spdy_util_2;
bnc87dcefc2017-05-25 12:47:5814641 auto spdy1_data = base::MakeUnique<SequencedSocketData>(
14642 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14643 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0314644 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14645
bncdf80d44fd2016-07-15 20:27:4114646 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914647 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314648 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114649 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314650 };
bnc42331402016-07-25 13:36:1514651 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114652 SpdySerializedFrame host2_resp_body(
14653 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314654 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114655 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914656 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314657 };
14658
bnc87dcefc2017-05-25 12:47:5814659 auto spdy2_data = base::MakeUnique<SequencedSocketData>(
14660 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14661 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0314662 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14663
14664 MockWrite http_write[] = {
14665 MockWrite("GET / HTTP/1.1\r\n"
14666 "Host: www.a.com\r\n"
14667 "Connection: keep-alive\r\n\r\n"),
14668 };
14669
14670 MockRead http_read[] = {
14671 MockRead("HTTP/1.1 200 OK\r\n"),
14672 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14673 MockRead("Content-Length: 6\r\n\r\n"),
14674 MockRead("hello!"),
14675 };
14676 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14677 http_write, arraysize(http_write));
14678 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14679
14680 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014681 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314682 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314683 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614684 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314685
14686 TestCompletionCallback callback;
14687 HttpRequestInfo request1;
14688 request1.method = "GET";
14689 request1.url = GURL("https://www.a.com/");
14690 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814691 auto trans =
14692 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314693
tfarina42834112016-09-22 13:38:2014694 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14696 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314697
14698 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214699 ASSERT_TRUE(response);
14700 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214701 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314702 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214703 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314704
14705 std::string response_data;
robpercival214763f2016-07-01 23:27:0114706 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314707 EXPECT_EQ("hello!", response_data);
14708 trans.reset();
14709 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614710 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314711
14712 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014713 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314714 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314715 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614716 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314717 HttpRequestInfo request2;
14718 request2.method = "GET";
14719 request2.url = GURL("https://www.b.com/");
14720 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814721 trans =
14722 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314723
tfarina42834112016-09-22 13:38:2014724 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14726 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314727
14728 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214729 ASSERT_TRUE(response);
14730 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214731 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314732 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214733 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114734 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314735 EXPECT_EQ("hello!", response_data);
14736 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614737 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314738 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614739 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314740
14741 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014742 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314743 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314744 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614745 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314746 HttpRequestInfo request3;
14747 request3.method = "GET";
14748 request3.url = GURL("http://www.a.com/");
14749 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814750 trans =
14751 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314752
tfarina42834112016-09-22 13:38:2014753 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114754 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14755 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314756
14757 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214758 ASSERT_TRUE(response);
14759 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314760 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14761 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214762 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114763 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314764 EXPECT_EQ("hello!", response_data);
14765 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614766 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314767 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614768 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314769}
14770
bncd16676a2016-07-20 16:23:0114771TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414772 HttpRequestInfo request;
14773 request.method = "GET";
bncce36dca22015-04-21 22:11:2314774 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414775
danakj1fd259a02016-04-16 03:17:0914776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414778
ttuttled9dbc652015-09-29 20:00:5914779 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414780 StaticSocketDataProvider data;
14781 data.set_connect_data(mock_connect);
14782 session_deps_.socket_factory->AddSocketDataProvider(&data);
14783
14784 TestCompletionCallback callback;
14785
tfarina42834112016-09-22 13:38:2014786 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414788
14789 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114790 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414791
[email protected]79e1fd62013-06-20 06:50:0414792 // We don't care whether this succeeds or fails, but it shouldn't crash.
14793 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614794 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714795
14796 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614797 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714798 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114799 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914800
14801 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614802 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914803 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414804}
14805
bncd16676a2016-07-20 16:23:0114806TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414807 HttpRequestInfo request;
14808 request.method = "GET";
bncce36dca22015-04-21 22:11:2314809 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414810
danakj1fd259a02016-04-16 03:17:0914811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414813
ttuttled9dbc652015-09-29 20:00:5914814 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414815 StaticSocketDataProvider data;
14816 data.set_connect_data(mock_connect);
14817 session_deps_.socket_factory->AddSocketDataProvider(&data);
14818
14819 TestCompletionCallback callback;
14820
tfarina42834112016-09-22 13:38:2014821 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414823
14824 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114825 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414826
[email protected]79e1fd62013-06-20 06:50:0414827 // We don't care whether this succeeds or fails, but it shouldn't crash.
14828 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614829 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714830
14831 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614832 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714833 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114834 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914835
14836 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614837 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914838 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414839}
14840
bncd16676a2016-07-20 16:23:0114841TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414842 HttpRequestInfo request;
14843 request.method = "GET";
bncce36dca22015-04-21 22:11:2314844 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414845
danakj1fd259a02016-04-16 03:17:0914846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614847 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414848
14849 MockWrite data_writes[] = {
14850 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14851 };
14852 MockRead data_reads[] = {
14853 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14854 };
14855
14856 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14857 data_writes, arraysize(data_writes));
14858 session_deps_.socket_factory->AddSocketDataProvider(&data);
14859
14860 TestCompletionCallback callback;
14861
tfarina42834112016-09-22 13:38:2014862 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414864
14865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114866 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414867
[email protected]79e1fd62013-06-20 06:50:0414868 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614869 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414870 EXPECT_TRUE(request_headers.HasHeader("Host"));
14871}
14872
bncd16676a2016-07-20 16:23:0114873TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414874 HttpRequestInfo request;
14875 request.method = "GET";
bncce36dca22015-04-21 22:11:2314876 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414877
danakj1fd259a02016-04-16 03:17:0914878 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614879 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414880
14881 MockWrite data_writes[] = {
14882 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14883 };
14884 MockRead data_reads[] = {
14885 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14886 };
14887
14888 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14889 data_writes, arraysize(data_writes));
14890 session_deps_.socket_factory->AddSocketDataProvider(&data);
14891
14892 TestCompletionCallback callback;
14893
tfarina42834112016-09-22 13:38:2014894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414896
14897 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114898 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414899
[email protected]79e1fd62013-06-20 06:50:0414900 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614901 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414902 EXPECT_TRUE(request_headers.HasHeader("Host"));
14903}
14904
bncd16676a2016-07-20 16:23:0114905TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414906 HttpRequestInfo request;
14907 request.method = "GET";
bncce36dca22015-04-21 22:11:2314908 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414909
danakj1fd259a02016-04-16 03:17:0914910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414912
14913 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314914 MockWrite(
14915 "GET / HTTP/1.1\r\n"
14916 "Host: www.example.org\r\n"
14917 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414918 };
14919 MockRead data_reads[] = {
14920 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14921 };
14922
14923 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14924 data_writes, arraysize(data_writes));
14925 session_deps_.socket_factory->AddSocketDataProvider(&data);
14926
14927 TestCompletionCallback callback;
14928
tfarina42834112016-09-22 13:38:2014929 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414931
14932 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114933 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414934
[email protected]79e1fd62013-06-20 06:50:0414935 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614936 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414937 EXPECT_TRUE(request_headers.HasHeader("Host"));
14938}
14939
bncd16676a2016-07-20 16:23:0114940TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414941 HttpRequestInfo request;
14942 request.method = "GET";
bncce36dca22015-04-21 22:11:2314943 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414944
danakj1fd259a02016-04-16 03:17:0914945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414947
14948 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314949 MockWrite(
14950 "GET / HTTP/1.1\r\n"
14951 "Host: www.example.org\r\n"
14952 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414953 };
14954 MockRead data_reads[] = {
14955 MockRead(ASYNC, ERR_CONNECTION_RESET),
14956 };
14957
14958 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14959 data_writes, arraysize(data_writes));
14960 session_deps_.socket_factory->AddSocketDataProvider(&data);
14961
14962 TestCompletionCallback callback;
14963
tfarina42834112016-09-22 13:38:2014964 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114965 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414966
14967 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114968 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414969
[email protected]79e1fd62013-06-20 06:50:0414970 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614971 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414972 EXPECT_TRUE(request_headers.HasHeader("Host"));
14973}
14974
bncd16676a2016-07-20 16:23:0114975TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414976 HttpRequestInfo request;
14977 request.method = "GET";
bncce36dca22015-04-21 22:11:2314978 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414979 request.extra_headers.SetHeader("X-Foo", "bar");
14980
danakj1fd259a02016-04-16 03:17:0914981 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414983
14984 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314985 MockWrite(
14986 "GET / HTTP/1.1\r\n"
14987 "Host: www.example.org\r\n"
14988 "Connection: keep-alive\r\n"
14989 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414990 };
14991 MockRead data_reads[] = {
14992 MockRead("HTTP/1.1 200 OK\r\n"
14993 "Content-Length: 5\r\n\r\n"
14994 "hello"),
14995 MockRead(ASYNC, ERR_UNEXPECTED),
14996 };
14997
14998 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14999 data_writes, arraysize(data_writes));
15000 session_deps_.socket_factory->AddSocketDataProvider(&data);
15001
15002 TestCompletionCallback callback;
15003
tfarina42834112016-09-22 13:38:2015004 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415006
15007 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115008 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415009
15010 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615011 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415012 std::string foo;
15013 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15014 EXPECT_EQ("bar", foo);
15015}
15016
[email protected]bf828982013-08-14 18:01:4715017namespace {
15018
yhiranoa7e05bb2014-11-06 05:40:3915019// Fake HttpStream that simply records calls to SetPriority().
15020class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315021 public base::SupportsWeakPtr<FakeStream> {
15022 public:
15023 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015024 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315025
15026 RequestPriority priority() const { return priority_; }
15027
dchengb03027d2014-10-21 12:00:2015028 int InitializeStream(const HttpRequestInfo* request_info,
15029 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015030 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015031 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315032 return ERR_IO_PENDING;
15033 }
15034
dchengb03027d2014-10-21 12:00:2015035 int SendRequest(const HttpRequestHeaders& request_headers,
15036 HttpResponseInfo* response,
15037 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315038 ADD_FAILURE();
15039 return ERR_UNEXPECTED;
15040 }
15041
dchengb03027d2014-10-21 12:00:2015042 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315043 ADD_FAILURE();
15044 return ERR_UNEXPECTED;
15045 }
15046
dchengb03027d2014-10-21 12:00:2015047 int ReadResponseBody(IOBuffer* buf,
15048 int buf_len,
15049 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315050 ADD_FAILURE();
15051 return ERR_UNEXPECTED;
15052 }
15053
dchengb03027d2014-10-21 12:00:2015054 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315055
dchengb03027d2014-10-21 12:00:2015056 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315057 ADD_FAILURE();
15058 return false;
15059 }
15060
dchengb03027d2014-10-21 12:00:2015061 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315062 ADD_FAILURE();
15063 return false;
15064 }
15065
dchengb03027d2014-10-21 12:00:2015066 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315067
mmenkebd84c392015-09-02 14:12:3415068 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315069
sclittle4de1bab92015-09-22 21:28:2415070 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915071 ADD_FAILURE();
15072 return 0;
15073 }
15074
sclittlebe1ccf62015-09-02 19:40:3615075 int64_t GetTotalSentBytes() const override {
15076 ADD_FAILURE();
15077 return 0;
15078 }
15079
dchengb03027d2014-10-21 12:00:2015080 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315081 ADD_FAILURE();
15082 return false;
15083 }
15084
rchcd379012017-04-12 21:53:3215085 bool GetAlternativeService(
15086 AlternativeService* alternative_service) const override {
15087 ADD_FAILURE();
15088 return false;
15089 }
15090
dchengb03027d2014-10-21 12:00:2015091 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15092
15093 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315094 ADD_FAILURE();
15095 }
15096
ttuttled9dbc652015-09-29 20:00:5915097 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15098
nharper78e6d2b2016-09-21 05:42:3515099 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15100 TokenBindingType tb_type,
15101 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415102 ADD_FAILURE();
15103 return ERR_NOT_IMPLEMENTED;
15104 }
15105
dchengb03027d2014-10-21 12:00:2015106 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315107
zhongyica364fbb2015-12-12 03:39:1215108 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15109
dchengb03027d2014-10-21 12:00:2015110 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315111
yhiranoa7e05bb2014-11-06 05:40:3915112 HttpStream* RenewStreamForAuth() override { return NULL; }
15113
[email protected]e86839fd2013-08-14 18:29:0315114 private:
15115 RequestPriority priority_;
15116
15117 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15118};
15119
15120// Fake HttpStreamRequest that simply records calls to SetPriority()
15121// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715122class FakeStreamRequest : public HttpStreamRequest,
15123 public base::SupportsWeakPtr<FakeStreamRequest> {
15124 public:
[email protected]e86839fd2013-08-14 18:29:0315125 FakeStreamRequest(RequestPriority priority,
15126 HttpStreamRequest::Delegate* delegate)
15127 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415128 delegate_(delegate),
15129 websocket_stream_create_helper_(NULL) {}
15130
15131 FakeStreamRequest(RequestPriority priority,
15132 HttpStreamRequest::Delegate* delegate,
15133 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15134 : priority_(priority),
15135 delegate_(delegate),
15136 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315137
dchengb03027d2014-10-21 12:00:2015138 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715139
15140 RequestPriority priority() const { return priority_; }
15141
[email protected]831e4a32013-11-14 02:14:4415142 const WebSocketHandshakeStreamBase::CreateHelper*
15143 websocket_stream_create_helper() const {
15144 return websocket_stream_create_helper_;
15145 }
15146
[email protected]e86839fd2013-08-14 18:29:0315147 // Create a new FakeStream and pass it to the request's
15148 // delegate. Returns a weak pointer to the FakeStream.
15149 base::WeakPtr<FakeStream> FinishStreamRequest() {
bnc5029f4632017-06-08 16:19:0015150 auto fake_stream = base::MakeUnique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315151 // Do this before calling OnStreamReady() as OnStreamReady() may
15152 // immediately delete |fake_stream|.
15153 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015154 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315155 return weak_stream;
15156 }
15157
asanka681f02d2017-02-22 17:06:3915158 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715159 ADD_FAILURE();
15160 return ERR_UNEXPECTED;
15161 }
15162
dchengb03027d2014-10-21 12:00:2015163 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715164 ADD_FAILURE();
15165 return LoadState();
15166 }
15167
dchengb03027d2014-10-21 12:00:2015168 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715169
bnc94c92842016-09-21 15:22:5215170 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715171
bnc6227b26e2016-08-12 02:00:4315172 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715173
dchengb03027d2014-10-21 12:00:2015174 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715175
ttuttle1f2d7e92015-04-28 16:17:4715176 const ConnectionAttempts& connection_attempts() const override {
15177 static ConnectionAttempts no_attempts;
15178 return no_attempts;
15179 }
15180
[email protected]bf828982013-08-14 18:01:4715181 private:
15182 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315183 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415184 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715185
15186 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15187};
15188
15189// Fake HttpStreamFactory that vends FakeStreamRequests.
15190class FakeStreamFactory : public HttpStreamFactory {
15191 public:
15192 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015193 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715194
15195 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15196 // RequestStream() (which may be NULL if it was destroyed already).
15197 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15198 return last_stream_request_;
15199 }
15200
xunjieli96f2a402017-06-05 17:24:2715201 std::unique_ptr<HttpStreamRequest> RequestStream(
15202 const HttpRequestInfo& info,
15203 RequestPriority priority,
15204 const SSLConfig& server_ssl_config,
15205 const SSLConfig& proxy_ssl_config,
15206 HttpStreamRequest::Delegate* delegate,
15207 bool enable_ip_based_pooling,
15208 bool enable_alternative_services,
15209 const NetLogWithSource& net_log) override {
15210 auto fake_request = base::MakeUnique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715211 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715212 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715213 }
15214
xunjieli96f2a402017-06-05 17:24:2715215 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815216 const HttpRequestInfo& info,
15217 RequestPriority priority,
15218 const SSLConfig& server_ssl_config,
15219 const SSLConfig& proxy_ssl_config,
15220 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915221 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615222 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015223 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815224 NOTREACHED();
15225 return nullptr;
15226 }
15227
xunjieli96f2a402017-06-05 17:24:2715228 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715229 const HttpRequestInfo& info,
15230 RequestPriority priority,
15231 const SSLConfig& server_ssl_config,
15232 const SSLConfig& proxy_ssl_config,
15233 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615234 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915235 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615236 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015237 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715238 auto fake_request =
15239 base::MakeUnique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415240 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715241 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715242 }
15243
dchengb03027d2014-10-21 12:00:2015244 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915245 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715246 ADD_FAILURE();
15247 }
15248
dchengb03027d2014-10-21 12:00:2015249 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715250 ADD_FAILURE();
15251 return NULL;
15252 }
15253
xunjielif5267de2017-01-20 21:18:5715254 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15255 const std::string& parent_absolute_name) const override {
15256 ADD_FAILURE();
15257 }
15258
[email protected]bf828982013-08-14 18:01:4715259 private:
15260 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15261
15262 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15263};
15264
Adam Rice425cf122015-01-19 06:18:2415265// TODO(ricea): Maybe unify this with the one in
15266// url_request_http_job_unittest.cc ?
15267class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15268 public:
danakj1fd259a02016-04-16 03:17:0915269 FakeWebSocketBasicHandshakeStream(
15270 std::unique_ptr<ClientSocketHandle> connection,
15271 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215272 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415273
15274 // Fake implementation of HttpStreamBase methods.
15275 // This ends up being quite "real" because this object has to really send data
15276 // on the mock socket. It might be easier to use the real implementation, but
15277 // the fact that the WebSocket code is not compiled on iOS makes that
15278 // difficult.
15279 int InitializeStream(const HttpRequestInfo* request_info,
15280 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015281 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415282 const CompletionCallback& callback) override {
15283 state_.Initialize(request_info, priority, net_log, callback);
15284 return OK;
15285 }
15286
15287 int SendRequest(const HttpRequestHeaders& request_headers,
15288 HttpResponseInfo* response,
15289 const CompletionCallback& callback) override {
15290 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15291 response, callback);
15292 }
15293
15294 int ReadResponseHeaders(const CompletionCallback& callback) override {
15295 return parser()->ReadResponseHeaders(callback);
15296 }
15297
15298 int ReadResponseBody(IOBuffer* buf,
15299 int buf_len,
15300 const CompletionCallback& callback) override {
15301 NOTREACHED();
15302 return ERR_IO_PENDING;
15303 }
15304
15305 void Close(bool not_reusable) override {
15306 if (parser())
15307 parser()->Close(true);
15308 }
15309
15310 bool IsResponseBodyComplete() const override {
15311 NOTREACHED();
15312 return false;
15313 }
15314
Adam Rice425cf122015-01-19 06:18:2415315 bool IsConnectionReused() const override {
15316 NOTREACHED();
15317 return false;
15318 }
15319 void SetConnectionReused() override { NOTREACHED(); }
15320
mmenkebd84c392015-09-02 14:12:3415321 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415322
sclittle4de1bab92015-09-22 21:28:2415323 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415324 NOTREACHED();
15325 return 0;
15326 }
15327
sclittlebe1ccf62015-09-02 19:40:3615328 int64_t GetTotalSentBytes() const override {
15329 NOTREACHED();
15330 return 0;
15331 }
15332
Adam Rice425cf122015-01-19 06:18:2415333 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15334 NOTREACHED();
15335 return false;
15336 }
15337
rchcd379012017-04-12 21:53:3215338 bool GetAlternativeService(
15339 AlternativeService* alternative_service) const override {
15340 ADD_FAILURE();
15341 return false;
15342 }
15343
Adam Ricecb76ac62015-02-20 05:33:2515344 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415345
15346 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15347 NOTREACHED();
15348 }
15349
ttuttled9dbc652015-09-29 20:00:5915350 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15351
nharper78e6d2b2016-09-21 05:42:3515352 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15353 TokenBindingType tb_type,
15354 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415355 ADD_FAILURE();
15356 return ERR_NOT_IMPLEMENTED;
15357 }
15358
Adam Rice425cf122015-01-19 06:18:2415359 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15360
zhongyica364fbb2015-12-12 03:39:1215361 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15362
Adam Rice425cf122015-01-19 06:18:2415363 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15364
Adam Rice425cf122015-01-19 06:18:2415365 HttpStream* RenewStreamForAuth() override {
15366 NOTREACHED();
15367 return nullptr;
15368 }
15369
15370 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915371 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415372 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915373 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415374 }
15375
15376 private:
15377 HttpStreamParser* parser() const { return state_.parser(); }
15378 HttpBasicState state_;
15379
15380 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15381};
15382
[email protected]831e4a32013-11-14 02:14:4415383// TODO(yhirano): Split this class out into a net/websockets file, if it is
15384// worth doing.
15385class FakeWebSocketStreamCreateHelper :
15386 public WebSocketHandshakeStreamBase::CreateHelper {
15387 public:
bnc615cf2f2017-05-19 18:53:2615388 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915389 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315390 bool using_proxy) override {
bnc615cf2f2017-05-19 18:53:2615391 return base::MakeUnique<FakeWebSocketBasicHandshakeStream>(
15392 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415393 }
15394
dchengb03027d2014-10-21 12:00:2015395 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415396
danakj1fd259a02016-04-16 03:17:0915397 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415398 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915399 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415400 }
15401};
15402
[email protected]bf828982013-08-14 18:01:4715403} // namespace
15404
15405// Make sure that HttpNetworkTransaction passes on its priority to its
15406// stream request on start.
bncd16676a2016-07-20 16:23:0115407TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915408 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215409 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715410 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915411 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715412
krasinc06a72a2016-12-21 03:42:4615413 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115414 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715415
wezca1070932016-05-26 20:30:5215416 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715417
[email protected]bf828982013-08-14 18:01:4715418 TestCompletionCallback callback;
15419 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015420 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715421
15422 base::WeakPtr<FakeStreamRequest> fake_request =
15423 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215424 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715425 EXPECT_EQ(LOW, fake_request->priority());
15426}
15427
15428// Make sure that HttpNetworkTransaction passes on its priority
15429// updates to its stream request.
bncd16676a2016-07-20 16:23:0115430TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915431 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215432 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715433 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915434 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715435
krasinc06a72a2016-12-21 03:42:4615436 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115437 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715438
[email protected]bf828982013-08-14 18:01:4715439 TestCompletionCallback callback;
15440 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015441 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715442
15443 base::WeakPtr<FakeStreamRequest> fake_request =
15444 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215445 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715446 EXPECT_EQ(LOW, fake_request->priority());
15447
15448 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215449 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715450 EXPECT_EQ(LOWEST, fake_request->priority());
15451}
15452
[email protected]e86839fd2013-08-14 18:29:0315453// Make sure that HttpNetworkTransaction passes on its priority
15454// updates to its stream.
bncd16676a2016-07-20 16:23:0115455TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215457 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315458 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915459 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315460
krasinc06a72a2016-12-21 03:42:4615461 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115462 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315463
[email protected]e86839fd2013-08-14 18:29:0315464 TestCompletionCallback callback;
15465 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015466 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315467
15468 base::WeakPtr<FakeStreamRequest> fake_request =
15469 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215470 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315471 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215472 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315473 EXPECT_EQ(LOW, fake_stream->priority());
15474
15475 trans.SetPriority(LOWEST);
15476 EXPECT_EQ(LOWEST, fake_stream->priority());
15477}
15478
bncd16676a2016-07-20 16:23:0115479TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415480 // The same logic needs to be tested for both ws: and wss: schemes, but this
15481 // test is already parameterised on NextProto, so it uses a loop to verify
15482 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315483 std::string test_cases[] = {"ws://www.example.org/",
15484 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415485 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915486 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215487 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415488 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15489 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315490 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915491 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415492
krasinc06a72a2016-12-21 03:42:4615493 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115494 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415495 trans.SetWebSocketHandshakeStreamCreateHelper(
15496 &websocket_stream_create_helper);
15497
[email protected]831e4a32013-11-14 02:14:4415498 TestCompletionCallback callback;
15499 request.method = "GET";
15500 request.url = GURL(test_cases[i]);
15501
15502 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015503 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415504
15505 base::WeakPtr<FakeStreamRequest> fake_request =
15506 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215507 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415508 EXPECT_EQ(&websocket_stream_create_helper,
15509 fake_request->websocket_stream_create_helper());
15510 }
15511}
15512
[email protected]043b68c82013-08-22 23:41:5215513// Tests that when a used socket is returned to the SSL socket pool, it's closed
15514// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115515TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215516 ClientSocketPoolManager::set_max_sockets_per_group(
15517 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15518 ClientSocketPoolManager::set_max_sockets_per_pool(
15519 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15520
15521 // Set up SSL request.
15522
15523 HttpRequestInfo ssl_request;
15524 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315525 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215526
15527 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315528 MockWrite(
15529 "GET / HTTP/1.1\r\n"
15530 "Host: www.example.org\r\n"
15531 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215532 };
15533 MockRead ssl_reads[] = {
15534 MockRead("HTTP/1.1 200 OK\r\n"),
15535 MockRead("Content-Length: 11\r\n\r\n"),
15536 MockRead("hello world"),
15537 MockRead(SYNCHRONOUS, OK),
15538 };
15539 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15540 ssl_writes, arraysize(ssl_writes));
15541 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15542
15543 SSLSocketDataProvider ssl(ASYNC, OK);
15544 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15545
15546 // Set up HTTP request.
15547
15548 HttpRequestInfo http_request;
15549 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315550 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215551
15552 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315553 MockWrite(
15554 "GET / HTTP/1.1\r\n"
15555 "Host: www.example.org\r\n"
15556 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215557 };
15558 MockRead http_reads[] = {
15559 MockRead("HTTP/1.1 200 OK\r\n"),
15560 MockRead("Content-Length: 7\r\n\r\n"),
15561 MockRead("falafel"),
15562 MockRead(SYNCHRONOUS, OK),
15563 };
15564 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15565 http_writes, arraysize(http_writes));
15566 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15567
danakj1fd259a02016-04-16 03:17:0915568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215569
15570 // Start the SSL request.
15571 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615572 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015573 ASSERT_EQ(ERR_IO_PENDING,
15574 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15575 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215576
15577 // Start the HTTP request. Pool should stall.
15578 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615579 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015580 ASSERT_EQ(ERR_IO_PENDING,
15581 http_trans.Start(&http_request, http_callback.callback(),
15582 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115583 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215584
15585 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115586 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215587 std::string response_data;
bnc691fda62016-08-12 00:43:1615588 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215589 EXPECT_EQ("hello world", response_data);
15590
15591 // The SSL socket should automatically be closed, so the HTTP request can
15592 // start.
dcheng48459ac22014-08-26 00:46:4115593 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15594 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215595
15596 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115597 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615598 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215599 EXPECT_EQ("falafel", response_data);
15600
dcheng48459ac22014-08-26 00:46:4115601 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215602}
15603
15604// Tests that when a SSL connection is established but there's no corresponding
15605// request that needs it, the new socket is closed if the transport socket pool
15606// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115607TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215608 ClientSocketPoolManager::set_max_sockets_per_group(
15609 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15610 ClientSocketPoolManager::set_max_sockets_per_pool(
15611 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15612
15613 // Set up an ssl request.
15614
15615 HttpRequestInfo ssl_request;
15616 ssl_request.method = "GET";
15617 ssl_request.url = GURL("https://www.foopy.com/");
15618
15619 // No data will be sent on the SSL socket.
15620 StaticSocketDataProvider ssl_data;
15621 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15622
15623 SSLSocketDataProvider ssl(ASYNC, OK);
15624 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15625
15626 // Set up HTTP request.
15627
15628 HttpRequestInfo http_request;
15629 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315630 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215631
15632 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315633 MockWrite(
15634 "GET / HTTP/1.1\r\n"
15635 "Host: www.example.org\r\n"
15636 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215637 };
15638 MockRead http_reads[] = {
15639 MockRead("HTTP/1.1 200 OK\r\n"),
15640 MockRead("Content-Length: 7\r\n\r\n"),
15641 MockRead("falafel"),
15642 MockRead(SYNCHRONOUS, OK),
15643 };
15644 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15645 http_writes, arraysize(http_writes));
15646 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15647
danakj1fd259a02016-04-16 03:17:0915648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215649
15650 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15651 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915652 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915653 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115654 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215655
15656 // Start the HTTP request. Pool should stall.
15657 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615658 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015659 ASSERT_EQ(ERR_IO_PENDING,
15660 http_trans.Start(&http_request, http_callback.callback(),
15661 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115662 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215663
15664 // The SSL connection will automatically be closed once the connection is
15665 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115666 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215667 std::string response_data;
bnc691fda62016-08-12 00:43:1615668 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215669 EXPECT_EQ("falafel", response_data);
15670
dcheng48459ac22014-08-26 00:46:4115671 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215672}
15673
bncd16676a2016-07-20 16:23:0115674TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915675 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215676 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715677 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215678 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415679
15680 HttpRequestInfo request;
15681 request.method = "POST";
15682 request.url = GURL("http://www.foo.com/");
15683 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415684
danakj1fd259a02016-04-16 03:17:0915685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615686 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415687 // Send headers successfully, but get an error while sending the body.
15688 MockWrite data_writes[] = {
15689 MockWrite("POST / HTTP/1.1\r\n"
15690 "Host: www.foo.com\r\n"
15691 "Connection: keep-alive\r\n"
15692 "Content-Length: 3\r\n\r\n"),
15693 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15694 };
15695
15696 MockRead data_reads[] = {
15697 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15698 MockRead("hello world"),
15699 MockRead(SYNCHRONOUS, OK),
15700 };
15701 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15702 arraysize(data_writes));
15703 session_deps_.socket_factory->AddSocketDataProvider(&data);
15704
15705 TestCompletionCallback callback;
15706
tfarina42834112016-09-22 13:38:2015707 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415709
15710 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115711 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415712
bnc691fda62016-08-12 00:43:1615713 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215714 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415715
wezca1070932016-05-26 20:30:5215716 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415717 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15718
15719 std::string response_data;
bnc691fda62016-08-12 00:43:1615720 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115721 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415722 EXPECT_EQ("hello world", response_data);
15723}
15724
15725// This test makes sure the retry logic doesn't trigger when reading an error
15726// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115727TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415728 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415730 MockWrite data_writes[] = {
15731 MockWrite("GET / HTTP/1.1\r\n"
15732 "Host: www.foo.com\r\n"
15733 "Connection: keep-alive\r\n\r\n"),
15734 MockWrite("POST / HTTP/1.1\r\n"
15735 "Host: www.foo.com\r\n"
15736 "Connection: keep-alive\r\n"
15737 "Content-Length: 3\r\n\r\n"),
15738 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15739 };
15740
15741 MockRead data_reads[] = {
15742 MockRead("HTTP/1.1 200 Peachy\r\n"
15743 "Content-Length: 14\r\n\r\n"),
15744 MockRead("first response"),
15745 MockRead("HTTP/1.1 400 Not OK\r\n"
15746 "Content-Length: 15\r\n\r\n"),
15747 MockRead("second response"),
15748 MockRead(SYNCHRONOUS, OK),
15749 };
15750 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15751 arraysize(data_writes));
15752 session_deps_.socket_factory->AddSocketDataProvider(&data);
15753
15754 TestCompletionCallback callback;
15755 HttpRequestInfo request1;
15756 request1.method = "GET";
15757 request1.url = GURL("http://www.foo.com/");
15758 request1.load_flags = 0;
15759
bnc87dcefc2017-05-25 12:47:5815760 auto trans1 =
15761 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015762 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415764
15765 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115766 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415767
15768 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215769 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415770
wezca1070932016-05-26 20:30:5215771 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415772 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15773
15774 std::string response_data1;
15775 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115776 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415777 EXPECT_EQ("first response", response_data1);
15778 // Delete the transaction to release the socket back into the socket pool.
15779 trans1.reset();
15780
danakj1fd259a02016-04-16 03:17:0915781 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215782 element_readers.push_back(
bnc87dcefc2017-05-25 12:47:5815783 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215784 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415785
15786 HttpRequestInfo request2;
15787 request2.method = "POST";
15788 request2.url = GURL("http://www.foo.com/");
15789 request2.upload_data_stream = &upload_data_stream;
15790 request2.load_flags = 0;
15791
bnc691fda62016-08-12 00:43:1615792 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015793 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415795
15796 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115797 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415798
bnc691fda62016-08-12 00:43:1615799 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215800 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415801
wezca1070932016-05-26 20:30:5215802 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415803 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15804
15805 std::string response_data2;
bnc691fda62016-08-12 00:43:1615806 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115807 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415808 EXPECT_EQ("second response", response_data2);
15809}
15810
bncd16676a2016-07-20 16:23:0115811TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415812 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915813 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215814 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715815 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215816 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415817
15818 HttpRequestInfo request;
15819 request.method = "POST";
15820 request.url = GURL("http://www.foo.com/");
15821 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415822
danakj1fd259a02016-04-16 03:17:0915823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415825 // Send headers successfully, but get an error while sending the body.
15826 MockWrite data_writes[] = {
15827 MockWrite("POST / HTTP/1.1\r\n"
15828 "Host: www.foo.com\r\n"
15829 "Connection: keep-alive\r\n"
15830 "Content-Length: 3\r\n\r\n"
15831 "fo"),
15832 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15833 };
15834
15835 MockRead data_reads[] = {
15836 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15837 MockRead("hello world"),
15838 MockRead(SYNCHRONOUS, OK),
15839 };
15840 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15841 arraysize(data_writes));
15842 session_deps_.socket_factory->AddSocketDataProvider(&data);
15843
15844 TestCompletionCallback callback;
15845
tfarina42834112016-09-22 13:38:2015846 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415848
15849 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115850 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415851
bnc691fda62016-08-12 00:43:1615852 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215853 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415854
wezca1070932016-05-26 20:30:5215855 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415856 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15857
15858 std::string response_data;
bnc691fda62016-08-12 00:43:1615859 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115860 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415861 EXPECT_EQ("hello world", response_data);
15862}
15863
15864// This tests the more common case than the previous test, where headers and
15865// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115866TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715867 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415868
15869 HttpRequestInfo request;
15870 request.method = "POST";
15871 request.url = GURL("http://www.foo.com/");
15872 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415873
danakj1fd259a02016-04-16 03:17:0915874 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615875 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415876 // Send headers successfully, but get an error while sending the body.
15877 MockWrite data_writes[] = {
15878 MockWrite("POST / HTTP/1.1\r\n"
15879 "Host: www.foo.com\r\n"
15880 "Connection: keep-alive\r\n"
15881 "Transfer-Encoding: chunked\r\n\r\n"),
15882 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15883 };
15884
15885 MockRead data_reads[] = {
15886 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15887 MockRead("hello world"),
15888 MockRead(SYNCHRONOUS, OK),
15889 };
15890 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15891 arraysize(data_writes));
15892 session_deps_.socket_factory->AddSocketDataProvider(&data);
15893
15894 TestCompletionCallback callback;
15895
tfarina42834112016-09-22 13:38:2015896 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415898 // Make sure the headers are sent before adding a chunk. This ensures that
15899 // they can't be merged with the body in a single send. Not currently
15900 // necessary since a chunked body is never merged with headers, but this makes
15901 // the test more future proof.
15902 base::RunLoop().RunUntilIdle();
15903
mmenkecbc2b712014-10-09 20:29:0715904 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415905
15906 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115907 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415908
bnc691fda62016-08-12 00:43:1615909 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215910 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415911
wezca1070932016-05-26 20:30:5215912 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415913 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15914
15915 std::string response_data;
bnc691fda62016-08-12 00:43:1615916 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115917 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415918 EXPECT_EQ("hello world", response_data);
15919}
15920
bncd16676a2016-07-20 16:23:0115921TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915922 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215923 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715924 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215925 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415926
15927 HttpRequestInfo request;
15928 request.method = "POST";
15929 request.url = GURL("http://www.foo.com/");
15930 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415931
danakj1fd259a02016-04-16 03:17:0915932 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615933 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415934
15935 MockWrite data_writes[] = {
15936 MockWrite("POST / HTTP/1.1\r\n"
15937 "Host: www.foo.com\r\n"
15938 "Connection: keep-alive\r\n"
15939 "Content-Length: 3\r\n\r\n"),
15940 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15941 };
15942
15943 MockRead data_reads[] = {
15944 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15945 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15946 MockRead("hello world"),
15947 MockRead(SYNCHRONOUS, OK),
15948 };
15949 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15950 arraysize(data_writes));
15951 session_deps_.socket_factory->AddSocketDataProvider(&data);
15952
15953 TestCompletionCallback callback;
15954
tfarina42834112016-09-22 13:38:2015955 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415957
15958 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115959 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415960
bnc691fda62016-08-12 00:43:1615961 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215962 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415963
wezca1070932016-05-26 20:30:5215964 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415965 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15966
15967 std::string response_data;
bnc691fda62016-08-12 00:43:1615968 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115969 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415970 EXPECT_EQ("hello world", response_data);
15971}
15972
bncd16676a2016-07-20 16:23:0115973TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915974 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215975 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715976 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215977 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415978
15979 HttpRequestInfo request;
15980 request.method = "POST";
15981 request.url = GURL("http://www.foo.com/");
15982 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415983
danakj1fd259a02016-04-16 03:17:0915984 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415986 // Send headers successfully, but get an error while sending the body.
15987 MockWrite data_writes[] = {
15988 MockWrite("POST / HTTP/1.1\r\n"
15989 "Host: www.foo.com\r\n"
15990 "Connection: keep-alive\r\n"
15991 "Content-Length: 3\r\n\r\n"),
15992 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15993 };
15994
15995 MockRead data_reads[] = {
15996 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15997 MockRead("hello world"),
15998 MockRead(SYNCHRONOUS, OK),
15999 };
16000 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16001 arraysize(data_writes));
16002 session_deps_.socket_factory->AddSocketDataProvider(&data);
16003
16004 TestCompletionCallback callback;
16005
tfarina42834112016-09-22 13:38:2016006 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416008
16009 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116010 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416011}
16012
bncd16676a2016-07-20 16:23:0116013TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416014 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916015 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216016 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716017 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216018 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416019
16020 HttpRequestInfo request;
16021 request.method = "POST";
16022 request.url = GURL("http://www.foo.com/");
16023 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416024
danakj1fd259a02016-04-16 03:17:0916025 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416027 // Send headers successfully, but get an error while sending the body.
16028 MockWrite data_writes[] = {
16029 MockWrite("POST / HTTP/1.1\r\n"
16030 "Host: www.foo.com\r\n"
16031 "Connection: keep-alive\r\n"
16032 "Content-Length: 3\r\n\r\n"),
16033 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16034 };
16035
16036 MockRead data_reads[] = {
16037 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16038 MockRead("HTTP/1.0 302 Redirect\r\n"),
16039 MockRead("Location: http://somewhere-else.com/\r\n"),
16040 MockRead("Content-Length: 0\r\n\r\n"),
16041 MockRead(SYNCHRONOUS, OK),
16042 };
16043 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16044 arraysize(data_writes));
16045 session_deps_.socket_factory->AddSocketDataProvider(&data);
16046
16047 TestCompletionCallback callback;
16048
tfarina42834112016-09-22 13:38:2016049 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116050 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416051
16052 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116053 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416054}
16055
bncd16676a2016-07-20 16:23:0116056TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916057 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216058 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716059 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216060 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416061
16062 HttpRequestInfo request;
16063 request.method = "POST";
16064 request.url = GURL("http://www.foo.com/");
16065 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416066
danakj1fd259a02016-04-16 03:17:0916067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416069 // Send headers successfully, but get an error while sending the body.
16070 MockWrite data_writes[] = {
16071 MockWrite("POST / HTTP/1.1\r\n"
16072 "Host: www.foo.com\r\n"
16073 "Connection: keep-alive\r\n"
16074 "Content-Length: 3\r\n\r\n"),
16075 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16076 };
16077
16078 MockRead data_reads[] = {
16079 MockRead("HTTP 0.9 rocks!"),
16080 MockRead(SYNCHRONOUS, OK),
16081 };
16082 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16083 arraysize(data_writes));
16084 session_deps_.socket_factory->AddSocketDataProvider(&data);
16085
16086 TestCompletionCallback callback;
16087
tfarina42834112016-09-22 13:38:2016088 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416090
16091 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116092 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416093}
16094
bncd16676a2016-07-20 16:23:0116095TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916096 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216097 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716098 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216099 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416100
16101 HttpRequestInfo request;
16102 request.method = "POST";
16103 request.url = GURL("http://www.foo.com/");
16104 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416105
danakj1fd259a02016-04-16 03:17:0916106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416108 // Send headers successfully, but get an error while sending the body.
16109 MockWrite data_writes[] = {
16110 MockWrite("POST / HTTP/1.1\r\n"
16111 "Host: www.foo.com\r\n"
16112 "Connection: keep-alive\r\n"
16113 "Content-Length: 3\r\n\r\n"),
16114 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16115 };
16116
16117 MockRead data_reads[] = {
16118 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16119 MockRead(SYNCHRONOUS, OK),
16120 };
16121 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16122 arraysize(data_writes));
16123 session_deps_.socket_factory->AddSocketDataProvider(&data);
16124
16125 TestCompletionCallback callback;
16126
tfarina42834112016-09-22 13:38:2016127 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116128 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416129
16130 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116131 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416132}
16133
Adam Rice425cf122015-01-19 06:18:2416134// Verify that proxy headers are not sent to the destination server when
16135// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116136TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416137 HttpRequestInfo request;
16138 request.method = "GET";
bncce36dca22015-04-21 22:11:2316139 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416140 AddWebSocketHeaders(&request.extra_headers);
16141
16142 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316143 session_deps_.proxy_service =
16144 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416145
danakj1fd259a02016-04-16 03:17:0916146 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416147
16148 // Since a proxy is configured, try to establish a tunnel.
16149 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716150 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16151 "Host: www.example.org:443\r\n"
16152 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416153
16154 // After calling trans->RestartWithAuth(), this is the request we should
16155 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716156 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16157 "Host: www.example.org:443\r\n"
16158 "Proxy-Connection: keep-alive\r\n"
16159 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416160
rsleevidb16bb02015-11-12 23:47:1716161 MockWrite("GET / HTTP/1.1\r\n"
16162 "Host: www.example.org\r\n"
16163 "Connection: Upgrade\r\n"
16164 "Upgrade: websocket\r\n"
16165 "Origin: http://www.example.org\r\n"
16166 "Sec-WebSocket-Version: 13\r\n"
16167 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416168 };
16169
16170 // The proxy responds to the connect with a 407, using a persistent
16171 // connection.
16172 MockRead data_reads[] = {
16173 // No credentials.
16174 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16175 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416176 MockRead("Content-Length: 0\r\n"),
16177 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416178
16179 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16180
16181 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16182 MockRead("Upgrade: websocket\r\n"),
16183 MockRead("Connection: Upgrade\r\n"),
16184 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16185 };
16186
16187 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16188 arraysize(data_writes));
16189 session_deps_.socket_factory->AddSocketDataProvider(&data);
16190 SSLSocketDataProvider ssl(ASYNC, OK);
16191 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16192
bnc87dcefc2017-05-25 12:47:5816193 auto trans =
16194 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416195 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16196 trans->SetWebSocketHandshakeStreamCreateHelper(
16197 &websocket_stream_create_helper);
16198
16199 {
16200 TestCompletionCallback callback;
16201
tfarina42834112016-09-22 13:38:2016202 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416204
16205 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116206 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416207 }
16208
16209 const HttpResponseInfo* response = trans->GetResponseInfo();
16210 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216211 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416212 EXPECT_EQ(407, response->headers->response_code());
16213
16214 {
16215 TestCompletionCallback callback;
16216
16217 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16218 callback.callback());
robpercival214763f2016-07-01 23:27:0116219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416220
16221 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116222 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416223 }
16224
16225 response = trans->GetResponseInfo();
16226 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216227 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416228
16229 EXPECT_EQ(101, response->headers->response_code());
16230
16231 trans.reset();
16232 session->CloseAllConnections();
16233}
16234
16235// Verify that proxy headers are not sent to the destination server when
16236// establishing a tunnel for an insecure WebSocket connection.
16237// This requires the authentication info to be injected into the auth cache
16238// due to crbug.com/395064
16239// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116240TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416241 HttpRequestInfo request;
16242 request.method = "GET";
bncce36dca22015-04-21 22:11:2316243 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416244 AddWebSocketHeaders(&request.extra_headers);
16245
16246 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316247 session_deps_.proxy_service =
16248 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416249
danakj1fd259a02016-04-16 03:17:0916250 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416251
16252 MockWrite data_writes[] = {
16253 // Try to establish a tunnel for the WebSocket connection, with
16254 // credentials. Because WebSockets have a separate set of socket pools,
16255 // they cannot and will not use the same TCP/IP connection as the
16256 // preflight HTTP request.
16257 MockWrite(
bncce36dca22015-04-21 22:11:2316258 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16259 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416260 "Proxy-Connection: keep-alive\r\n"
16261 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16262
16263 MockWrite(
16264 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316265 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416266 "Connection: Upgrade\r\n"
16267 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316268 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416269 "Sec-WebSocket-Version: 13\r\n"
16270 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16271 };
16272
16273 MockRead data_reads[] = {
16274 // HTTP CONNECT with credentials.
16275 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16276
16277 // WebSocket connection established inside tunnel.
16278 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16279 MockRead("Upgrade: websocket\r\n"),
16280 MockRead("Connection: Upgrade\r\n"),
16281 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16282 };
16283
16284 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16285 arraysize(data_writes));
16286 session_deps_.socket_factory->AddSocketDataProvider(&data);
16287
16288 session->http_auth_cache()->Add(
16289 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16290 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16291
bnc87dcefc2017-05-25 12:47:5816292 auto trans =
16293 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416294 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16295 trans->SetWebSocketHandshakeStreamCreateHelper(
16296 &websocket_stream_create_helper);
16297
16298 TestCompletionCallback callback;
16299
tfarina42834112016-09-22 13:38:2016300 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116301 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416302
16303 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116304 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416305
16306 const HttpResponseInfo* response = trans->GetResponseInfo();
16307 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216308 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416309
16310 EXPECT_EQ(101, response->headers->response_code());
16311
16312 trans.reset();
16313 session->CloseAllConnections();
16314}
16315
bncd16676a2016-07-20 16:23:0116316TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916317 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216318 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716319 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216320 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216321
16322 HttpRequestInfo request;
16323 request.method = "POST";
16324 request.url = GURL("http://www.foo.com/");
16325 request.upload_data_stream = &upload_data_stream;
16326
danakj1fd259a02016-04-16 03:17:0916327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616328 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216329 MockWrite data_writes[] = {
16330 MockWrite("POST / HTTP/1.1\r\n"
16331 "Host: www.foo.com\r\n"
16332 "Connection: keep-alive\r\n"
16333 "Content-Length: 3\r\n\r\n"),
16334 MockWrite("foo"),
16335 };
16336
16337 MockRead data_reads[] = {
16338 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16339 MockRead(SYNCHRONOUS, OK),
16340 };
16341 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16342 arraysize(data_writes));
16343 session_deps_.socket_factory->AddSocketDataProvider(&data);
16344
16345 TestCompletionCallback callback;
16346
16347 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016348 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116349 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216350
16351 std::string response_data;
bnc691fda62016-08-12 00:43:1616352 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216353
16354 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616355 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216356 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616357 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216358}
16359
bncd16676a2016-07-20 16:23:0116360TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916361 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216362 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716363 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216364 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216365
16366 HttpRequestInfo request;
16367 request.method = "POST";
16368 request.url = GURL("http://www.foo.com/");
16369 request.upload_data_stream = &upload_data_stream;
16370
danakj1fd259a02016-04-16 03:17:0916371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216373 MockWrite data_writes[] = {
16374 MockWrite("POST / HTTP/1.1\r\n"
16375 "Host: www.foo.com\r\n"
16376 "Connection: keep-alive\r\n"
16377 "Content-Length: 3\r\n\r\n"),
16378 MockWrite("foo"),
16379 };
16380
16381 MockRead data_reads[] = {
16382 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16383 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16384 MockRead(SYNCHRONOUS, OK),
16385 };
16386 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16387 arraysize(data_writes));
16388 session_deps_.socket_factory->AddSocketDataProvider(&data);
16389
16390 TestCompletionCallback callback;
16391
16392 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016393 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116394 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216395
16396 std::string response_data;
bnc691fda62016-08-12 00:43:1616397 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216398
16399 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616400 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216401 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616402 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216403}
16404
bncd16676a2016-07-20 16:23:0116405TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216406 ChunkedUploadDataStream upload_data_stream(0);
16407
16408 HttpRequestInfo request;
16409 request.method = "POST";
16410 request.url = GURL("http://www.foo.com/");
16411 request.upload_data_stream = &upload_data_stream;
16412
danakj1fd259a02016-04-16 03:17:0916413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616414 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216415 // Send headers successfully, but get an error while sending the body.
16416 MockWrite data_writes[] = {
16417 MockWrite("POST / HTTP/1.1\r\n"
16418 "Host: www.foo.com\r\n"
16419 "Connection: keep-alive\r\n"
16420 "Transfer-Encoding: chunked\r\n\r\n"),
16421 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16422 };
16423
16424 MockRead data_reads[] = {
16425 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16426 MockRead(SYNCHRONOUS, OK),
16427 };
16428 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16429 arraysize(data_writes));
16430 session_deps_.socket_factory->AddSocketDataProvider(&data);
16431
16432 TestCompletionCallback callback;
16433
16434 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016435 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216436
16437 base::RunLoop().RunUntilIdle();
16438 upload_data_stream.AppendData("f", 1, false);
16439
16440 base::RunLoop().RunUntilIdle();
16441 upload_data_stream.AppendData("oo", 2, true);
16442
robpercival214763f2016-07-01 23:27:0116443 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216444
16445 std::string response_data;
bnc691fda62016-08-12 00:43:1616446 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216447
16448 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616449 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216450 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616451 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216452}
16453
rdsmith1d343be52016-10-21 20:37:5016454// Confirm that transactions whose throttle is created in (and stays in)
16455// the unthrottled state are not blocked.
16456TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16457 TestNetworkStreamThrottler* throttler(nullptr);
16458 std::unique_ptr<HttpNetworkSession> session(
16459 CreateSessionWithThrottler(&session_deps_, &throttler));
16460
16461 // Send a simple request and make sure it goes through.
16462 HttpRequestInfo request;
16463 request.method = "GET";
16464 request.url = GURL("http://www.example.org/");
16465
bnc87dcefc2017-05-25 12:47:5816466 auto trans =
16467 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016468
16469 MockWrite data_writes[] = {
16470 MockWrite("GET / HTTP/1.1\r\n"
16471 "Host: www.example.org\r\n"
16472 "Connection: keep-alive\r\n\r\n"),
16473 };
16474 MockRead data_reads[] = {
16475 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16476 MockRead(SYNCHRONOUS, OK),
16477 };
16478 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16479 arraysize(data_writes));
16480 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16481
16482 TestCompletionCallback callback;
16483 trans->Start(&request, callback.callback(), NetLogWithSource());
16484 EXPECT_EQ(OK, callback.WaitForResult());
16485}
16486
16487// Confirm requests can be blocked by a throttler, and are resumed
16488// when the throttle is unblocked.
16489TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16490 TestNetworkStreamThrottler* throttler(nullptr);
16491 std::unique_ptr<HttpNetworkSession> session(
16492 CreateSessionWithThrottler(&session_deps_, &throttler));
16493
16494 // Send a simple request and make sure it goes through.
16495 HttpRequestInfo request;
16496 request.method = "GET";
16497 request.url = GURL("http://www.example.org/");
16498
16499 MockWrite data_writes[] = {
16500 MockWrite("GET / HTTP/1.1\r\n"
16501 "Host: www.example.org\r\n"
16502 "Connection: keep-alive\r\n\r\n"),
16503 };
16504 MockRead data_reads[] = {
16505 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16506 MockRead(SYNCHRONOUS, OK),
16507 };
16508 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16509 arraysize(data_writes));
16510 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16511
16512 // Start a request that will be throttled at start; confirm it
16513 // doesn't complete.
16514 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816515 auto trans =
16516 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016517
16518 TestCompletionCallback callback;
16519 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16520 EXPECT_EQ(ERR_IO_PENDING, rv);
16521
16522 base::RunLoop().RunUntilIdle();
16523 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16524 EXPECT_FALSE(callback.have_result());
16525
16526 // Confirm the request goes on to complete when unthrottled.
16527 throttler->UnthrottleAllRequests();
16528 base::RunLoop().RunUntilIdle();
16529 ASSERT_TRUE(callback.have_result());
16530 EXPECT_EQ(OK, callback.WaitForResult());
16531}
16532
16533// Destroy a request while it's throttled.
16534TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16535 TestNetworkStreamThrottler* throttler(nullptr);
16536 std::unique_ptr<HttpNetworkSession> session(
16537 CreateSessionWithThrottler(&session_deps_, &throttler));
16538
16539 // Send a simple request and make sure it goes through.
16540 HttpRequestInfo request;
16541 request.method = "GET";
16542 request.url = GURL("http://www.example.org/");
16543
16544 MockWrite data_writes[] = {
16545 MockWrite("GET / HTTP/1.1\r\n"
16546 "Host: www.example.org\r\n"
16547 "Connection: keep-alive\r\n\r\n"),
16548 };
16549 MockRead data_reads[] = {
16550 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16551 MockRead(SYNCHRONOUS, OK),
16552 };
16553 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16554 arraysize(data_writes));
16555 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16556
16557 // Start a request that will be throttled at start; confirm it
16558 // doesn't complete.
16559 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816560 auto trans =
16561 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016562
16563 TestCompletionCallback callback;
16564 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16565 EXPECT_EQ(ERR_IO_PENDING, rv);
16566
16567 base::RunLoop().RunUntilIdle();
16568 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16569 EXPECT_FALSE(callback.have_result());
16570
16571 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16572 trans.reset();
16573 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16574}
16575
16576// Confirm the throttler receives SetPriority calls.
16577TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16578 TestNetworkStreamThrottler* throttler(nullptr);
16579 std::unique_ptr<HttpNetworkSession> session(
16580 CreateSessionWithThrottler(&session_deps_, &throttler));
16581
16582 // Send a simple request and make sure it goes through.
16583 HttpRequestInfo request;
16584 request.method = "GET";
16585 request.url = GURL("http://www.example.org/");
16586
16587 MockWrite data_writes[] = {
16588 MockWrite("GET / HTTP/1.1\r\n"
16589 "Host: www.example.org\r\n"
16590 "Connection: keep-alive\r\n\r\n"),
16591 };
16592 MockRead data_reads[] = {
16593 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16594 MockRead(SYNCHRONOUS, OK),
16595 };
16596 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16597 arraysize(data_writes));
16598 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16599
16600 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816601 auto trans = base::MakeUnique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016602 // Start the transaction to associate a throttle with it.
16603 TestCompletionCallback callback;
16604 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16605 EXPECT_EQ(ERR_IO_PENDING, rv);
16606
16607 EXPECT_EQ(0, throttler->num_set_priority_calls());
16608 trans->SetPriority(LOW);
16609 EXPECT_EQ(1, throttler->num_set_priority_calls());
16610 EXPECT_EQ(LOW, throttler->last_priority_set());
16611
16612 throttler->UnthrottleAllRequests();
16613 base::RunLoop().RunUntilIdle();
16614 ASSERT_TRUE(callback.have_result());
16615 EXPECT_EQ(OK, callback.WaitForResult());
16616}
16617
16618// Confirm that unthrottling from a SetPriority call by the
16619// throttler works properly.
16620TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16621 TestNetworkStreamThrottler* throttler(nullptr);
16622 std::unique_ptr<HttpNetworkSession> session(
16623 CreateSessionWithThrottler(&session_deps_, &throttler));
16624
16625 // Send a simple request and make sure it goes through.
16626 HttpRequestInfo request;
16627 request.method = "GET";
16628 request.url = GURL("http://www.example.org/");
16629
16630 MockWrite data_writes[] = {
16631 MockWrite("GET / HTTP/1.1\r\n"
16632 "Host: www.example.org\r\n"
16633 "Connection: keep-alive\r\n\r\n"),
16634 };
16635 MockRead data_reads[] = {
16636 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16637 MockRead(SYNCHRONOUS, OK),
16638 };
16639 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16640 arraysize(data_writes));
16641 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16642
16643 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16644 data_writes, arraysize(data_writes));
16645 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16646
16647 // Start a request that will be throttled at start; confirm it
16648 // doesn't complete.
16649 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816650 auto trans =
16651 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016652
16653 TestCompletionCallback callback;
16654 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16655 EXPECT_EQ(ERR_IO_PENDING, rv);
16656
16657 base::RunLoop().RunUntilIdle();
16658 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16659 EXPECT_FALSE(callback.have_result());
16660
16661 // Create a new request, call SetPriority on it to unthrottle,
16662 // and make sure that allows the original request to complete.
bnc87dcefc2017-05-25 12:47:5816663 auto trans1 = base::MakeUnique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5016664 throttler->set_priority_change_closure(
16665 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16666 base::Unretained(throttler)));
16667
16668 // Start the transaction to associate a throttle with it.
16669 TestCompletionCallback callback1;
16670 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16671 EXPECT_EQ(ERR_IO_PENDING, rv);
16672
16673 trans1->SetPriority(IDLE);
16674
16675 base::RunLoop().RunUntilIdle();
16676 ASSERT_TRUE(callback.have_result());
16677 EXPECT_EQ(OK, callback.WaitForResult());
16678 ASSERT_TRUE(callback1.have_result());
16679 EXPECT_EQ(OK, callback1.WaitForResult());
16680}
16681
16682// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5816683void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5016684
16685// Confirm that destroying a transaction from a SetPriority call by the
16686// throttler works properly.
16687TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16688 TestNetworkStreamThrottler* throttler(nullptr);
16689 std::unique_ptr<HttpNetworkSession> session(
16690 CreateSessionWithThrottler(&session_deps_, &throttler));
16691
16692 // Send a simple request and make sure it goes through.
16693 HttpRequestInfo request;
16694 request.method = "GET";
16695 request.url = GURL("http://www.example.org/");
16696
16697 MockWrite data_writes[] = {
16698 MockWrite("GET / HTTP/1.1\r\n"
16699 "Host: www.example.org\r\n"
16700 "Connection: keep-alive\r\n\r\n"),
16701 };
16702 MockRead data_reads[] = {
16703 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16704 MockRead(SYNCHRONOUS, OK),
16705 };
16706 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16707 arraysize(data_writes));
16708 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16709
16710 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16711 data_writes, arraysize(data_writes));
16712 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16713
16714 // Start a request that will be throttled at start; confirm it
16715 // doesn't complete.
16716 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816717 auto trans =
16718 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016719
16720 TestCompletionCallback callback;
16721 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16722 EXPECT_EQ(ERR_IO_PENDING, rv);
16723
16724 base::RunLoop().RunUntilIdle();
16725 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16726 EXPECT_FALSE(callback.have_result());
16727
16728 // Arrange for the set priority call on the above transaction to delete
16729 // the transaction.
bnc87dcefc2017-05-25 12:47:5816730 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5016731 throttler->set_priority_change_closure(
16732 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16733
16734 // Call it and check results (partially a "doesn't crash" test).
16735 trans_ptr->SetPriority(IDLE);
16736 trans_ptr = nullptr; // No longer a valid pointer.
16737
16738 base::RunLoop().RunUntilIdle();
16739 ASSERT_FALSE(callback.have_result());
16740}
16741
nharperb7441ef2016-01-25 23:54:1416742#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116743TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416744 const std::string https_url = "https://www.example.com";
16745 HttpRequestInfo request;
16746 request.url = GURL(https_url);
16747 request.method = "GET";
16748
16749 SSLSocketDataProvider ssl(ASYNC, OK);
16750 ssl.token_binding_negotiated = true;
16751 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616752 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16754
bnc42331402016-07-25 13:36:1516755 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116756 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16757 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416758 MockRead(ASYNC, ERR_IO_PENDING)};
16759 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16760 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5816761 session_deps_.channel_id_service =
16762 base::MakeUnique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0916763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416764
16765 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16766 TestCompletionCallback callback;
16767 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016768 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1016769
16770 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416771
16772 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16773 HttpRequestHeaders headers;
16774 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16775 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16776}
16777#endif // !defined(OS_IOS)
16778
eustasc7d27da2017-04-06 10:33:2016779void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
16780 const std::string& accept_encoding,
16781 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0316782 const std::string& location,
eustasc7d27da2017-04-06 10:33:2016783 bool should_match) {
16784 HttpRequestInfo request;
16785 request.method = "GET";
16786 request.url = GURL("http://www.foo.com/");
16787 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
16788 accept_encoding);
16789
16790 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
16791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16792 // Send headers successfully, but get an error while sending the body.
16793 MockWrite data_writes[] = {
16794 MockWrite("GET / HTTP/1.1\r\n"
16795 "Host: www.foo.com\r\n"
16796 "Connection: keep-alive\r\n"
16797 "Accept-Encoding: "),
16798 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
16799 };
16800
sky50576f32017-05-01 19:28:0316801 std::string response_code = "200 OK";
16802 std::string extra;
16803 if (!location.empty()) {
16804 response_code = "301 Redirect\r\nLocation: ";
16805 response_code.append(location);
16806 }
16807
eustasc7d27da2017-04-06 10:33:2016808 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0316809 MockRead("HTTP/1.0 "),
16810 MockRead(response_code.data()),
16811 MockRead("\r\nContent-Encoding: "),
16812 MockRead(content_encoding.data()),
16813 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2016814 MockRead(SYNCHRONOUS, OK),
16815 };
16816 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16817 arraysize(data_writes));
16818 session_deps->socket_factory->AddSocketDataProvider(&data);
16819
16820 TestCompletionCallback callback;
16821
16822 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16824
16825 rv = callback.WaitForResult();
16826 if (should_match) {
16827 EXPECT_THAT(rv, IsOk());
16828 } else {
16829 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
16830 }
16831}
16832
16833TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0316834 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2016835}
16836
16837TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0316838 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
16839 true);
eustasc7d27da2017-04-06 10:33:2016840}
16841
16842TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
16843 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0316844 "", false);
16845}
16846
16847TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
16848 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
16849 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2016850}
16851
xunjieli96f2a402017-06-05 17:24:2716852TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
16853 ProxyConfig proxy_config;
16854 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
16855 proxy_config.set_pac_mandatory(true);
16856 MockAsyncProxyResolver resolver;
16857 session_deps_.proxy_service.reset(new ProxyService(
16858 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
16859 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
16860
16861 HttpRequestInfo request;
16862 request.method = "GET";
16863 request.url = GURL("http://www.example.org/");
16864
16865 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16866 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16867
16868 TestCompletionCallback callback;
16869
16870 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16872 EXPECT_THAT(callback.WaitForResult(),
16873 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
16874}
16875
16876TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
16877 ProxyConfig proxy_config;
16878 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
16879 proxy_config.set_pac_mandatory(true);
16880 MockAsyncProxyResolverFactory* proxy_resolver_factory =
16881 new MockAsyncProxyResolverFactory(false);
16882 MockAsyncProxyResolver resolver;
16883 session_deps_.proxy_service.reset(
16884 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
16885 base::WrapUnique(proxy_resolver_factory), nullptr));
16886 HttpRequestInfo request;
16887 request.method = "GET";
16888 request.url = GURL("http://www.example.org/");
16889
16890 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16891 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16892
16893 TestCompletionCallback callback;
16894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16896
16897 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
16898 ERR_FAILED, &resolver);
16899 EXPECT_THAT(callback.WaitForResult(),
16900 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
16901}
16902
16903TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
16904 session_deps_.proxy_service =
16905 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
16906 session_deps_.enable_quic = false;
16907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16908
16909 HttpRequestInfo request;
16910 request.method = "GET";
16911 request.url = GURL("http://www.example.org/");
16912
16913 TestCompletionCallback callback;
16914 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16915 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16916 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16917
16918 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
16919}
16920
[email protected]89ceba9a2009-03-21 03:46:0616921} // namespace net