blob: c5a32fe527d6de0ea9f003a266f5910c8c99176d [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
rdsmith1d343be52016-10-21 20:37:5012#include <set>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
[email protected]68bf9152008-09-25 19:47:3017#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2919#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5720#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2421#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4622#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0923#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4724#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4925#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4726#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0527#include "base/strings/utf_string_conversions.h"
fdorayf33fede2017-05-11 21:18:1028#include "base/test/scoped_task_environment.h"
[email protected]f36a8132011-09-02 18:36:3329#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3530#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3531#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0732#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3333#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0734#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2535#include "net/base/load_timing_info.h"
36#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2437#include "net/base/net_errors.h"
rdsmith1d343be52016-10-21 20:37:5038#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1539#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3140#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5241#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1542#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0643#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2144#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1145#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1646#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5347#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2448#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1249#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0050#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2951#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1952#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2453#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5754#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5255#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5656#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2457#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1358#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5359#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5760#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3861#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2462#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1963#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0764#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0065#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1966#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5167#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4668#include "net/log/test_net_log_entry.h"
69#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1370#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5371#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0372#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1173#include "net/proxy/proxy_resolver.h"
xunjieli96f2a402017-06-05 17:24:2774#include "net/proxy/proxy_resolver_factory.h"
tbansal28e68f82016-02-04 02:56:1575#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1176#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4477#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1578#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0379#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4780#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0281#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0782#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4483#include "net/socket/socket_test_util.h"
84#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0685#include "net/spdy/chromium/spdy_session.h"
86#include "net/spdy/chromium/spdy_session_pool.h"
87#include "net/spdy/chromium/spdy_test_util_common.h"
88#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1489#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5790#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0391#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5792#include "net/ssl/ssl_config_service_defaults.h"
93#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5494#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1195#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0196#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1097#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:4398#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:4499#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:18100#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52101#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15102#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27103#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52104
robpercival214763f2016-07-01 23:27:01105using net::test::IsError;
106using net::test::IsOk;
107
[email protected]ad65a3e2013-12-25 18:18:01108using base::ASCIIToUTF16;
109
initial.commit586acc5fe2008-07-26 22:42:52110//-----------------------------------------------------------------------------
111
ttuttle859dc7a2015-04-23 19:42:29112namespace net {
113
[email protected]13c8a092010-07-29 06:15:44114namespace {
115
rdsmith1d343be52016-10-21 20:37:50116class TestNetworkStreamThrottler : public NetworkThrottleManager {
117 public:
118 TestNetworkStreamThrottler()
119 : throttle_new_requests_(false),
120 num_set_priority_calls_(0),
121 last_priority_set_(IDLE) {}
122
123 ~TestNetworkStreamThrottler() override {
124 EXPECT_TRUE(outstanding_throttles_.empty());
125 }
126
127 // NetworkThrottleManager
128 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
129 RequestPriority priority,
130 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58131 auto test_throttle =
132 base::MakeUnique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50133 outstanding_throttles_.insert(test_throttle.get());
134 return std::move(test_throttle);
135 }
136
137 void UnthrottleAllRequests() {
138 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25139 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24140 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50141 throttle->Unthrottle();
142 }
143 }
144
145 void set_throttle_new_requests(bool throttle_new_requests) {
146 throttle_new_requests_ = throttle_new_requests;
147 }
148
149 // Includes both throttled and unthrottled throttles.
150 size_t num_outstanding_requests() const {
151 return outstanding_throttles_.size();
152 }
153
154 int num_set_priority_calls() const { return num_set_priority_calls_; }
155 RequestPriority last_priority_set() const { return last_priority_set_; }
156 void set_priority_change_closure(
157 const base::Closure& priority_change_closure) {
158 priority_change_closure_ = priority_change_closure;
159 }
160
161 private:
162 class TestThrottle : public NetworkThrottleManager::Throttle {
163 public:
164 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
165
166 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24167 bool IsBlocked() const override { return throttled_; }
168 RequestPriority Priority() const override {
169 NOTREACHED();
170 return IDLE;
171 }
rdsmith1d343be52016-10-21 20:37:50172 void SetPriority(RequestPriority priority) override {
173 throttler_->SetPriorityCalled(priority);
174 }
175
176 TestThrottle(bool throttled,
177 ThrottleDelegate* delegate,
178 TestNetworkStreamThrottler* throttler)
179 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
180
181 void Unthrottle() {
182 EXPECT_TRUE(throttled_);
183
184 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24185 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50186 }
187
188 bool throttled_;
189 ThrottleDelegate* delegate_;
190 TestNetworkStreamThrottler* throttler_;
191 };
192
193 void OnThrottleDestroyed(TestThrottle* throttle) {
194 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
195 outstanding_throttles_.erase(throttle);
196 }
197
198 void SetPriorityCalled(RequestPriority priority) {
199 ++num_set_priority_calls_;
200 last_priority_set_ = priority;
201 if (!priority_change_closure_.is_null())
202 priority_change_closure_.Run();
203 }
204
205 // Includes both throttled and unthrottled throttles.
206 std::set<TestThrottle*> outstanding_throttles_;
207 bool throttle_new_requests_;
208 int num_set_priority_calls_;
209 RequestPriority last_priority_set_;
210 base::Closure priority_change_closure_;
211
212 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
213};
214
[email protected]42cba2fb2013-03-29 19:58:57215const base::string16 kBar(ASCIIToUTF16("bar"));
216const base::string16 kBar2(ASCIIToUTF16("bar2"));
217const base::string16 kBar3(ASCIIToUTF16("bar3"));
218const base::string16 kBaz(ASCIIToUTF16("baz"));
219const base::string16 kFirst(ASCIIToUTF16("first"));
220const base::string16 kFoo(ASCIIToUTF16("foo"));
221const base::string16 kFoo2(ASCIIToUTF16("foo2"));
222const base::string16 kFoo3(ASCIIToUTF16("foo3"));
223const base::string16 kFou(ASCIIToUTF16("fou"));
224const base::string16 kSecond(ASCIIToUTF16("second"));
225const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
226const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44227
bnc2df4b522016-07-08 18:17:43228const char kAlternativeServiceHttpHeader[] =
229 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
230
ttuttle859dc7a2015-04-23 19:42:29231int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
232 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
233 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02234}
235
ttuttle859dc7a2015-04-23 19:42:29236int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
237 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
238 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02239}
240
ttuttle859dc7a2015-04-23 19:42:29241bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
242 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
243 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52244}
245
[email protected]f3da152d2012-06-02 01:00:57246// Takes in a Value created from a NetLogHttpResponseParameter, and returns
247// a JSONified list of headers as a single string. Uses single quotes instead
248// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27249bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57250 if (!params)
251 return false;
[email protected]ea5ef4c2013-06-13 22:50:27252 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57253 if (!params->GetList("headers", &header_list))
254 return false;
255 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34256 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28257 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57258 return true;
259}
260
[email protected]029c83b62013-01-24 05:28:20261// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
262// used.
ttuttle859dc7a2015-04-23 19:42:29263void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20264 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19265 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25266
[email protected]029c83b62013-01-24 05:28:20267 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
268 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
269
ttuttle859dc7a2015-04-23 19:42:29270 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20271 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25272
273 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25274
[email protected]3b23a222013-05-15 21:33:25275 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25276 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
277 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25278 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25279}
280
[email protected]029c83b62013-01-24 05:28:20281// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
282// used.
ttuttle859dc7a2015-04-23 19:42:29283void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25284 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20285 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19286 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20287
288 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
289 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
290
ttuttle859dc7a2015-04-23 19:42:29291 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
292 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20293 EXPECT_LE(load_timing_info.connect_timing.connect_end,
294 load_timing_info.send_start);
295
296 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20297
[email protected]3b23a222013-05-15 21:33:25298 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20299 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
300 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25301 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20302}
303
304// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
305// used.
ttuttle859dc7a2015-04-23 19:42:29306void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20307 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19308 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20309
ttuttle859dc7a2015-04-23 19:42:29310 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20311
312 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
313 EXPECT_LE(load_timing_info.proxy_resolve_start,
314 load_timing_info.proxy_resolve_end);
315 EXPECT_LE(load_timing_info.proxy_resolve_end,
316 load_timing_info.send_start);
317 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20318
[email protected]3b23a222013-05-15 21:33:25319 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20320 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
321 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25322 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20323}
324
325// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
326// used.
ttuttle859dc7a2015-04-23 19:42:29327void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20328 int connect_timing_flags) {
329 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19330 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20331
332 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
333 EXPECT_LE(load_timing_info.proxy_resolve_start,
334 load_timing_info.proxy_resolve_end);
335 EXPECT_LE(load_timing_info.proxy_resolve_end,
336 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29337 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
338 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20339 EXPECT_LE(load_timing_info.connect_timing.connect_end,
340 load_timing_info.send_start);
341
342 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20343
[email protected]3b23a222013-05-15 21:33:25344 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20345 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
346 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25347 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25348}
349
ttuttle859dc7a2015-04-23 19:42:29350void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24351 headers->SetHeader("Connection", "Upgrade");
352 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23353 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24354 headers->SetHeader("Sec-WebSocket-Version", "13");
355 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
356}
357
danakj1fd259a02016-04-16 03:17:09358std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42359 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34360 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14361}
362
rdsmith1d343be52016-10-21 20:37:50363// Note that the pointer written into |*throttler| will only be valid
364// for the lifetime of the returned HttpNetworkSession.
365std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
366 SpdySessionDependencies* session_deps,
367 TestNetworkStreamThrottler** throttler) {
368 std::unique_ptr<HttpNetworkSession> session(
369 SpdySessionDependencies::SpdyCreateSession(session_deps));
370
bnc87dcefc2017-05-25 12:47:58371 auto owned_throttler = base::MakeUnique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50372 *throttler = owned_throttler.get();
373
374 HttpNetworkSessionPeer peer(session.get());
375 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
376
377 return session;
378}
379
xunjieli96f2a402017-06-05 17:24:27380class FailingProxyResolverFactory : public ProxyResolverFactory {
381 public:
382 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
383
384 // ProxyResolverFactory override.
385 int CreateProxyResolver(
386 const scoped_refptr<ProxyResolverScriptData>& script_data,
387 std::unique_ptr<ProxyResolver>* result,
388 const CompletionCallback& callback,
389 std::unique_ptr<Request>* request) override {
390 return ERR_PAC_SCRIPT_FAILED;
391 }
392};
393
[email protected]448d4ca52012-03-04 04:12:23394} // namespace
395
bncd16676a2016-07-20 16:23:01396class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03397 public:
bncd16676a2016-07-20 16:23:01398 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03399 // Important to restore the per-pool limit first, since the pool limit must
400 // always be greater than group limit, and the tests reduce both limits.
401 ClientSocketPoolManager::set_max_sockets_per_pool(
402 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
403 ClientSocketPoolManager::set_max_sockets_per_group(
404 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
405 }
406
[email protected]e3ceb682011-06-28 23:55:46407 protected:
[email protected]23e482282013-06-14 16:08:02408 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15409 : ssl_(ASYNC, OK),
410 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03411 HttpNetworkSession::NORMAL_SOCKET_POOL)),
412 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
413 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28414 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03415 }
[email protected]bb88e1d32013-05-03 23:11:07416
[email protected]e3ceb682011-06-28 23:55:46417 struct SimpleGetHelperResult {
418 int rv;
419 std::string status_line;
420 std::string response_data;
sclittlefb249892015-09-10 21:33:22421 int64_t total_received_bytes;
422 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25423 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47424 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59425 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46426 };
427
dcheng67be2b1f2014-10-27 21:47:29428 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50429 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55430 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54431 }
432
dcheng67be2b1f2014-10-27 21:47:29433 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50434 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55435 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09436 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55437 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09438 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50439 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55440 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09441 }
442
[email protected]202965992011-12-07 23:04:51443 // Either |write_failure| specifies a write failure or |read_failure|
444 // specifies a read failure when using a reused socket. In either case, the
445 // failure should cause the network transaction to resend the request, and the
446 // other argument should be NULL.
447 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
448 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52449
[email protected]a34f61ee2014-03-18 20:59:49450 // Either |write_failure| specifies a write failure or |read_failure|
451 // specifies a read failure when using a reused socket. In either case, the
452 // failure should cause the network transaction to resend the request, and the
453 // other argument should be NULL.
454 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10455 const MockRead* read_failure,
456 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49457
[email protected]5a60c8b2011-10-19 20:14:29458 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
459 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15460 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52461
[email protected]ff007e162009-05-23 09:13:15462 HttpRequestInfo request;
463 request.method = "GET";
bncce36dca22015-04-21 22:11:23464 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52465
vishal.b62985ca92015-04-17 08:45:51466 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07467 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27470
[email protected]5a60c8b2011-10-19 20:14:29471 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07472 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29473 }
initial.commit586acc5fe2008-07-26 22:42:52474
[email protected]49639fa2011-12-20 23:22:41475 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52476
eroman24bc6a12015-05-06 19:55:48477 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16478 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52480
[email protected]ff007e162009-05-23 09:13:15481 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16482 out.total_received_bytes = trans.GetTotalReceivedBytes();
483 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25484
485 // Even in the failure cases that use this function, connections are always
486 // successfully established before the error.
bnc691fda62016-08-12 00:43:16487 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25488 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
489
[email protected]ff007e162009-05-23 09:13:15490 if (out.rv != OK)
491 return out;
492
bnc691fda62016-08-12 00:43:16493 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50494 // Can't use ASSERT_* inside helper functions like this, so
495 // return an error.
wezca1070932016-05-26 20:30:52496 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50497 out.rv = ERR_UNEXPECTED;
498 return out;
499 }
[email protected]ff007e162009-05-23 09:13:15500 out.status_line = response->headers->GetStatusLine();
501
[email protected]80a09a82012-11-16 17:40:06502 EXPECT_EQ("127.0.0.1", response->socket_address.host());
503 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19504
ttuttled9dbc652015-09-29 20:00:59505 bool got_endpoint =
bnc691fda62016-08-12 00:43:16506 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59507 EXPECT_EQ(got_endpoint,
508 out.remote_endpoint_after_start.address().size() > 0);
509
bnc691fda62016-08-12 00:43:16510 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01511 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40512
mmenke43758e62015-05-04 21:09:46513 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40514 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39515 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00516 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
517 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39518 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00519 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
520 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15521
[email protected]f3da152d2012-06-02 01:00:57522 std::string line;
523 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
524 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
525
[email protected]79e1fd62013-06-20 06:50:04526 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16527 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04528 std::string value;
529 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23530 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04531 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
532 EXPECT_EQ("keep-alive", value);
533
534 std::string response_headers;
535 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23536 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04537 response_headers);
[email protected]3deb9a52010-11-11 00:24:40538
bnc691fda62016-08-12 00:43:16539 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22540 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16541 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22542
bnc691fda62016-08-12 00:43:16543 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47544 return out;
[email protected]ff007e162009-05-23 09:13:15545 }
initial.commit586acc5fe2008-07-26 22:42:52546
[email protected]5a60c8b2011-10-19 20:14:29547 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
548 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22549 MockWrite data_writes[] = {
550 MockWrite("GET / HTTP/1.1\r\n"
551 "Host: www.example.org\r\n"
552 "Connection: keep-alive\r\n\r\n"),
553 };
[email protected]5a60c8b2011-10-19 20:14:29554
sclittlefb249892015-09-10 21:33:22555 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
556 arraysize(data_writes));
557 StaticSocketDataProvider* data[] = {&reads};
558 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
559
560 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
561 out.total_sent_bytes);
562 return out;
[email protected]b8015c42013-12-24 15:18:19563 }
564
bnc032658ba2016-09-26 18:17:15565 void AddSSLSocketData() {
566 ssl_.next_proto = kProtoHTTP2;
567 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
568 ASSERT_TRUE(ssl_.cert);
569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
570 }
571
[email protected]ff007e162009-05-23 09:13:15572 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
573 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52574
[email protected]ff007e162009-05-23 09:13:15575 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07576
577 void BypassHostCacheOnRefreshHelper(int load_flags);
578
579 void CheckErrorIsPassedBack(int error, IoMode mode);
580
[email protected]4bd46222013-05-14 19:32:23581 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07582 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15583 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03584
585 // Original socket limits. Some tests set these. Safest to always restore
586 // them once each test has been run.
587 int old_max_group_sockets_;
588 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15589};
[email protected]231d5a32008-09-13 00:45:27590
[email protected]448d4ca52012-03-04 04:12:23591namespace {
592
ryansturm49a8cb12016-06-15 16:51:09593class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27594 public:
ryansturm49a8cb12016-06-15 16:51:09595 BeforeHeadersSentHandler()
596 : observed_before_headers_sent_with_proxy_(false),
597 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27598
ryansturm49a8cb12016-06-15 16:51:09599 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
600 HttpRequestHeaders* request_headers) {
601 observed_before_headers_sent_ = true;
602 if (!proxy_info.is_http() && !proxy_info.is_https() &&
603 !proxy_info.is_quic()) {
604 return;
605 }
606 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27607 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
608 }
609
ryansturm49a8cb12016-06-15 16:51:09610 bool observed_before_headers_sent_with_proxy() const {
611 return observed_before_headers_sent_with_proxy_;
612 }
613
614 bool observed_before_headers_sent() const {
615 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27616 }
617
618 std::string observed_proxy_server_uri() const {
619 return observed_proxy_server_uri_;
620 }
621
622 private:
ryansturm49a8cb12016-06-15 16:51:09623 bool observed_before_headers_sent_with_proxy_;
624 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27625 std::string observed_proxy_server_uri_;
626
ryansturm49a8cb12016-06-15 16:51:09627 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27628};
629
[email protected]15a5ccf82008-10-23 19:57:43630// Fill |str| with a long header list that consumes >= |size| bytes.
631void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51632 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19633 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
634 const int sizeof_row = strlen(row);
635 const int num_rows = static_cast<int>(
636 ceil(static_cast<float>(size) / sizeof_row));
637 const int sizeof_data = num_rows * sizeof_row;
638 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43639 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51640
[email protected]4ddaf2502008-10-23 18:26:19641 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43642 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19643}
644
thakis84dff942015-07-28 20:47:38645#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29646// Alternative functions that eliminate randomness and dependency on the local
647// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14648void MockGenerateRandom1(uint8_t* output, size_t n) {
649 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
650 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29651 static size_t current_byte = 0;
652 for (size_t i = 0; i < n; ++i) {
653 output[i] = bytes[current_byte++];
654 current_byte %= arraysize(bytes);
655 }
656}
657
avibf0746c2015-12-09 19:53:14658void MockGenerateRandom2(uint8_t* output, size_t n) {
659 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
660 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
661 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29662 static size_t current_byte = 0;
663 for (size_t i = 0; i < n; ++i) {
664 output[i] = bytes[current_byte++];
665 current_byte %= arraysize(bytes);
666 }
667}
668
[email protected]fe2bc6a2009-03-23 16:52:20669std::string MockGetHostName() {
670 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29671}
thakis84dff942015-07-28 20:47:38672#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29673
[email protected]e60e47a2010-07-14 03:37:18674template<typename ParentPool>
675class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31676 public:
[email protected]9e1bdd32011-02-03 21:48:34677 CaptureGroupNameSocketPool(HostResolver* host_resolver,
678 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18679
[email protected]d80a4322009-08-14 07:07:49680 const std::string last_group_name_received() const {
681 return last_group_name_;
682 }
683
dmichaeld6e570d2014-12-18 22:30:57684 int RequestSocket(const std::string& group_name,
685 const void* socket_params,
686 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15687 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57688 ClientSocketHandle* handle,
689 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20690 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31691 last_group_name_ = group_name;
692 return ERR_IO_PENDING;
693 }
dmichaeld6e570d2014-12-18 22:30:57694 void CancelRequest(const std::string& group_name,
695 ClientSocketHandle* handle) override {}
696 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09697 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57698 int id) override {}
699 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23700 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57701 int IdleSocketCount() const override { return 0; }
702 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31703 return 0;
704 }
dmichaeld6e570d2014-12-18 22:30:57705 LoadState GetLoadState(const std::string& group_name,
706 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31707 return LOAD_STATE_IDLE;
708 }
dmichaeld6e570d2014-12-18 22:30:57709 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26710 return base::TimeDelta();
711 }
[email protected]d80a4322009-08-14 07:07:49712
713 private:
[email protected]04e5be32009-06-26 20:00:31714 std::string last_group_name_;
715};
716
[email protected]ab739042011-04-07 15:22:28717typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
718CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13719typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
720CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06721typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11722CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18723typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
724CaptureGroupNameSSLSocketPool;
725
rkaplowd90695c2015-03-25 22:12:41726template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18727CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34728 HostResolver* host_resolver,
729 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21730 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18731
hashimoto0d3e4fb2015-01-09 05:02:50732template <>
[email protected]2df19bb2010-08-25 20:13:46733CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21734 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34735 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09736 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46737
[email protected]007b3f82013-04-09 08:46:45738template <>
[email protected]e60e47a2010-07-14 03:37:18739CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21740 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34741 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45742 : SSLClientSocketPool(0,
743 0,
[email protected]007b3f82013-04-09 08:46:45744 cert_verifier,
745 NULL,
746 NULL,
[email protected]284303b62013-11-28 15:11:54747 NULL,
eranm6571b2b2014-12-03 15:53:23748 NULL,
[email protected]007b3f82013-04-09 08:46:45749 std::string(),
750 NULL,
751 NULL,
752 NULL,
753 NULL,
754 NULL,
[email protected]8e458552014-08-05 00:02:15755 NULL) {
756}
[email protected]2227c692010-05-04 15:36:11757
[email protected]231d5a32008-09-13 00:45:27758//-----------------------------------------------------------------------------
759
[email protected]79cb5c12011-09-12 13:12:04760// Helper functions for validating that AuthChallengeInfo's are correctly
761// configured for common cases.
762bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
763 if (!auth_challenge)
764 return false;
765 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43766 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04767 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19768 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04769 return true;
770}
771
772bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
773 if (!auth_challenge)
774 return false;
775 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43776 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
777 EXPECT_EQ("MyRealm1", auth_challenge->realm);
778 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
779 return true;
780}
781
782bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
783 if (!auth_challenge)
784 return false;
785 EXPECT_TRUE(auth_challenge->is_proxy);
786 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04787 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19788 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04789 return true;
790}
791
792bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
793 if (!auth_challenge)
794 return false;
795 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43796 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04797 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19798 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04799 return true;
800}
801
thakis84dff942015-07-28 20:47:38802#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04803bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
804 if (!auth_challenge)
805 return false;
806 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43807 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04808 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19809 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04810 return true;
811}
thakis84dff942015-07-28 20:47:38812#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04813
[email protected]448d4ca52012-03-04 04:12:23814} // namespace
815
bncd16676a2016-07-20 16:23:01816TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09817 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16818 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27819}
820
bncd16676a2016-07-20 16:23:01821TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27822 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35823 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
824 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06825 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27826 };
[email protected]31a2bfe2010-02-09 08:03:39827 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
828 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01829 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27830 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
831 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22832 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
833 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47834 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59835
836 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27837}
838
839// Response with no status line.
bncd16676a2016-07-20 16:23:01840TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27841 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35842 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06843 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27844 };
[email protected]31a2bfe2010-02-09 08:03:39845 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
846 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41847 EXPECT_THAT(out.rv, IsOk());
848 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
849 EXPECT_EQ("hello world", out.response_data);
850 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
851 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27852}
853
mmenkea7da6da2016-09-01 21:56:52854// Response with no status line, and a weird port. Should fail by default.
855TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
856 MockRead data_reads[] = {
857 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
858 };
859
860 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
861 session_deps_.socket_factory->AddSocketDataProvider(&data);
862
863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
864
krasinc06a72a2016-12-21 03:42:46865 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58866 auto trans =
867 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52868
mmenkea7da6da2016-09-01 21:56:52869 request.method = "GET";
870 request.url = GURL("http://www.example.com:2000/");
871 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20872 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52873 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
874}
875
876// Response with no status line, and a weird port. Option to allow weird ports
877// enabled.
878TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
879 MockRead data_reads[] = {
880 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
881 };
882
883 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
884 session_deps_.socket_factory->AddSocketDataProvider(&data);
885 session_deps_.http_09_on_non_default_ports_enabled = true;
886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
887
krasinc06a72a2016-12-21 03:42:46888 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58889 auto trans =
890 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52891
mmenkea7da6da2016-09-01 21:56:52892 request.method = "GET";
893 request.url = GURL("http://www.example.com:2000/");
894 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20895 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52896 EXPECT_THAT(callback.GetResult(rv), IsOk());
897
898 const HttpResponseInfo* info = trans->GetResponseInfo();
899 ASSERT_TRUE(info->headers);
900 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
901
902 // Don't bother to read the body - that's verified elsewhere, important thing
903 // is that the option to allow HTTP/0.9 on non-default ports is respected.
904}
905
[email protected]231d5a32008-09-13 00:45:27906// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01907TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27908 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35909 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06910 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27911 };
[email protected]31a2bfe2010-02-09 08:03:39912 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
913 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01914 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27915 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
916 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22917 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
918 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27919}
920
921// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01922TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27923 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35924 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06925 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27926 };
[email protected]31a2bfe2010-02-09 08:03:39927 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
928 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01929 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27930 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
931 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22932 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
933 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27934}
935
936// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01937TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27938 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35939 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06940 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27941 };
[email protected]31a2bfe2010-02-09 08:03:39942 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
943 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41944 EXPECT_THAT(out.rv, IsOk());
945 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
946 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
947 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
948 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27949}
950
951// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01952TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27953 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35954 MockRead("\n"),
955 MockRead("\n"),
956 MockRead("Q"),
957 MockRead("J"),
958 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06959 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27960 };
[email protected]31a2bfe2010-02-09 08:03:39961 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
962 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01963 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27964 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
965 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22966 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
967 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27968}
969
970// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01971TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27972 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35973 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06974 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27975 };
[email protected]31a2bfe2010-02-09 08:03:39976 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
977 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41978 EXPECT_THAT(out.rv, IsOk());
979 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
980 EXPECT_EQ("HTT", out.response_data);
981 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
982 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52983}
984
[email protected]f9d44aa2008-09-23 23:57:17985// Simulate a 204 response, lacking a Content-Length header, sent over a
986// persistent connection. The response should still terminate since a 204
987// cannot have a response body.
bncd16676a2016-07-20 16:23:01988TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19989 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17990 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35991 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19992 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06993 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17994 };
[email protected]31a2bfe2010-02-09 08:03:39995 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
996 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01997 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17998 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
999 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221000 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1001 int64_t response_size = reads_size - strlen(junk);
1002 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171003}
1004
[email protected]0877e3d2009-10-17 22:29:571005// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011006TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191007 std::string final_chunk = "0\r\n\r\n";
1008 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1009 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571010 MockRead data_reads[] = {
1011 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1012 MockRead("5\r\nHello\r\n"),
1013 MockRead("1\r\n"),
1014 MockRead(" \r\n"),
1015 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191016 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061017 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571018 };
[email protected]31a2bfe2010-02-09 08:03:391019 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1020 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011021 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571022 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1023 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221024 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1025 int64_t response_size = reads_size - extra_data.size();
1026 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571027}
1028
[email protected]9fe44f52010-09-23 18:36:001029// Next tests deal with http://crbug.com/56344.
1030
bncd16676a2016-07-20 16:23:011031TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001032 MultipleContentLengthHeadersNoTransferEncoding) {
1033 MockRead data_reads[] = {
1034 MockRead("HTTP/1.1 200 OK\r\n"),
1035 MockRead("Content-Length: 10\r\n"),
1036 MockRead("Content-Length: 5\r\n\r\n"),
1037 };
1038 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1039 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011040 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001041}
1042
bncd16676a2016-07-20 16:23:011043TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041044 DuplicateContentLengthHeadersNoTransferEncoding) {
1045 MockRead data_reads[] = {
1046 MockRead("HTTP/1.1 200 OK\r\n"),
1047 MockRead("Content-Length: 5\r\n"),
1048 MockRead("Content-Length: 5\r\n\r\n"),
1049 MockRead("Hello"),
1050 };
1051 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1052 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011053 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041054 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1055 EXPECT_EQ("Hello", out.response_data);
1056}
1057
bncd16676a2016-07-20 16:23:011058TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041059 ComplexContentLengthHeadersNoTransferEncoding) {
1060 // More than 2 dupes.
1061 {
1062 MockRead data_reads[] = {
1063 MockRead("HTTP/1.1 200 OK\r\n"),
1064 MockRead("Content-Length: 5\r\n"),
1065 MockRead("Content-Length: 5\r\n"),
1066 MockRead("Content-Length: 5\r\n\r\n"),
1067 MockRead("Hello"),
1068 };
1069 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1070 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011071 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041072 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1073 EXPECT_EQ("Hello", out.response_data);
1074 }
1075 // HTTP/1.0
1076 {
1077 MockRead data_reads[] = {
1078 MockRead("HTTP/1.0 200 OK\r\n"),
1079 MockRead("Content-Length: 5\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n\r\n"),
1082 MockRead("Hello"),
1083 };
1084 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1085 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011086 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041087 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1088 EXPECT_EQ("Hello", out.response_data);
1089 }
1090 // 2 dupes and one mismatched.
1091 {
1092 MockRead data_reads[] = {
1093 MockRead("HTTP/1.1 200 OK\r\n"),
1094 MockRead("Content-Length: 10\r\n"),
1095 MockRead("Content-Length: 10\r\n"),
1096 MockRead("Content-Length: 5\r\n\r\n"),
1097 };
1098 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1099 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011100 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041101 }
1102}
1103
bncd16676a2016-07-20 16:23:011104TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001105 MultipleContentLengthHeadersTransferEncoding) {
1106 MockRead data_reads[] = {
1107 MockRead("HTTP/1.1 200 OK\r\n"),
1108 MockRead("Content-Length: 666\r\n"),
1109 MockRead("Content-Length: 1337\r\n"),
1110 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1111 MockRead("5\r\nHello\r\n"),
1112 MockRead("1\r\n"),
1113 MockRead(" \r\n"),
1114 MockRead("5\r\nworld\r\n"),
1115 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061116 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001117 };
1118 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1119 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011120 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001121 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1122 EXPECT_EQ("Hello world", out.response_data);
1123}
1124
[email protected]1628fe92011-10-04 23:04:551125// Next tests deal with http://crbug.com/98895.
1126
1127// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011128TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551129 MockRead data_reads[] = {
1130 MockRead("HTTP/1.1 200 OK\r\n"),
1131 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1132 MockRead("Content-Length: 5\r\n\r\n"),
1133 MockRead("Hello"),
1134 };
1135 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1136 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011137 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551138 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1139 EXPECT_EQ("Hello", out.response_data);
1140}
1141
[email protected]54a9c6e52012-03-21 20:10:591142// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011143TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551144 MockRead data_reads[] = {
1145 MockRead("HTTP/1.1 200 OK\r\n"),
1146 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1147 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1148 MockRead("Content-Length: 5\r\n\r\n"),
1149 MockRead("Hello"),
1150 };
1151 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1152 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011153 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591154 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1155 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551156}
1157
1158// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011159TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551160 MockRead data_reads[] = {
1161 MockRead("HTTP/1.1 200 OK\r\n"),
1162 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1163 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1164 MockRead("Content-Length: 5\r\n\r\n"),
1165 MockRead("Hello"),
1166 };
1167 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1168 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011169 EXPECT_THAT(out.rv,
1170 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551171}
1172
[email protected]54a9c6e52012-03-21 20:10:591173// Checks that two identical Location headers result in no error.
1174// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011175TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551176 MockRead data_reads[] = {
1177 MockRead("HTTP/1.1 302 Redirect\r\n"),
1178 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591179 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551180 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061181 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551182 };
1183
1184 HttpRequestInfo request;
1185 request.method = "GET";
1186 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551187
danakj1fd259a02016-04-16 03:17:091188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161189 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551190
1191 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071192 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551193
[email protected]49639fa2011-12-20 23:22:411194 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551195
tfarina42834112016-09-22 13:38:201196 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551198
robpercival214763f2016-07-01 23:27:011199 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551200
bnc691fda62016-08-12 00:43:161201 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521202 ASSERT_TRUE(response);
1203 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551204 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1205 std::string url;
1206 EXPECT_TRUE(response->headers->IsRedirect(&url));
1207 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471208 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551209}
1210
[email protected]1628fe92011-10-04 23:04:551211// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011212TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551213 MockRead data_reads[] = {
1214 MockRead("HTTP/1.1 302 Redirect\r\n"),
1215 MockRead("Location: http://good.com/\r\n"),
1216 MockRead("Location: http://evil.com/\r\n"),
1217 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061218 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551219 };
1220 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1221 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011222 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551223}
1224
[email protected]ef0faf2e72009-03-05 23:27:231225// Do a request using the HEAD method. Verify that we don't try to read the
1226// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011227TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421228 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231229 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231230 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231231
danakj1fd259a02016-04-16 03:17:091232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091234 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161235 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091236 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1237 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271238
[email protected]ef0faf2e72009-03-05 23:27:231239 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131240 MockWrite("HEAD / HTTP/1.1\r\n"
1241 "Host: www.example.org\r\n"
1242 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231243 };
1244 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231245 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1246 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231247
mmenked39192ee2015-12-09 00:57:231248 // No response body because the test stops reading here.
1249 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231250 };
1251
[email protected]31a2bfe2010-02-09 08:03:391252 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1253 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071254 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231255
[email protected]49639fa2011-12-20 23:22:411256 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231257
tfarina42834112016-09-22 13:38:201258 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011259 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231260
1261 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011262 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231263
bnc691fda62016-08-12 00:43:161264 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521265 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231266
1267 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521268 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231269 EXPECT_EQ(1234, response->headers->GetContentLength());
1270 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471271 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091272 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1273 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231274
1275 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101276 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231277 bool has_server_header = response->headers->EnumerateHeader(
1278 &iter, "Server", &server_header);
1279 EXPECT_TRUE(has_server_header);
1280 EXPECT_EQ("Blah", server_header);
1281
1282 // Reading should give EOF right away, since there is no message body
1283 // (despite non-zero content-length).
1284 std::string response_data;
bnc691fda62016-08-12 00:43:161285 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011286 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231287 EXPECT_EQ("", response_data);
1288}
1289
bncd16676a2016-07-20 16:23:011290TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521292
1293 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351294 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1295 MockRead("hello"),
1296 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1297 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061298 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521299 };
[email protected]31a2bfe2010-02-09 08:03:391300 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071301 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521302
[email protected]0b0bf032010-09-21 18:08:501303 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521304 "hello", "world"
1305 };
1306
1307 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421308 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521309 request.method = "GET";
bncce36dca22015-04-21 22:11:231310 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521311
bnc691fda62016-08-12 00:43:161312 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271313
[email protected]49639fa2011-12-20 23:22:411314 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521315
tfarina42834112016-09-22 13:38:201316 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521318
1319 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011320 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521321
bnc691fda62016-08-12 00:43:161322 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521323 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521324
wezca1070932016-05-26 20:30:521325 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251326 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471327 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521328
1329 std::string response_data;
bnc691fda62016-08-12 00:43:161330 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011331 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251332 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521333 }
1334}
1335
bncd16676a2016-07-20 16:23:011336TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091337 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221338 element_readers.push_back(
ricea2deef682016-09-09 08:04:071339 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221340 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271341
[email protected]1c773ea12009-04-28 19:58:421342 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521343 request.method = "POST";
1344 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271345 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521346
shivanishab9a143952016-09-19 17:23:411347 // Check the upload progress returned before initialization is correct.
1348 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1349 EXPECT_EQ(0u, progress.size());
1350 EXPECT_EQ(0u, progress.position());
1351
danakj1fd259a02016-04-16 03:17:091352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271354
initial.commit586acc5fe2008-07-26 22:42:521355 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351356 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1357 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1358 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061359 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521360 };
[email protected]31a2bfe2010-02-09 08:03:391361 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071362 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521363
[email protected]49639fa2011-12-20 23:22:411364 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521365
tfarina42834112016-09-22 13:38:201366 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521368
1369 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011370 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521371
bnc691fda62016-08-12 00:43:161372 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521373 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521374
wezca1070932016-05-26 20:30:521375 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251376 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521377
1378 std::string response_data;
bnc691fda62016-08-12 00:43:161379 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011380 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251381 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521382}
1383
[email protected]3a2d3662009-03-27 03:49:141384// This test is almost the same as Ignores100 above, but the response contains
1385// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571386// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011387TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421388 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141389 request.method = "GET";
1390 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141391
danakj1fd259a02016-04-16 03:17:091392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271394
[email protected]3a2d3662009-03-27 03:49:141395 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571396 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1397 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141398 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061399 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141400 };
[email protected]31a2bfe2010-02-09 08:03:391401 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071402 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141403
[email protected]49639fa2011-12-20 23:22:411404 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141405
tfarina42834112016-09-22 13:38:201406 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141408
1409 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011410 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141411
bnc691fda62016-08-12 00:43:161412 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521413 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141414
wezca1070932016-05-26 20:30:521415 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141416 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1417
1418 std::string response_data;
bnc691fda62016-08-12 00:43:161419 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011420 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141421 EXPECT_EQ("hello world", response_data);
1422}
1423
bncd16676a2016-07-20 16:23:011424TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081425 HttpRequestInfo request;
1426 request.method = "POST";
1427 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081428
danakj1fd259a02016-04-16 03:17:091429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161430 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081431
1432 MockRead data_reads[] = {
1433 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1434 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381435 };
zmo9528c9f42015-08-04 22:12:081436 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1437 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381438
zmo9528c9f42015-08-04 22:12:081439 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381440
tfarina42834112016-09-22 13:38:201441 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011442 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381443
zmo9528c9f42015-08-04 22:12:081444 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011445 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381446
zmo9528c9f42015-08-04 22:12:081447 std::string response_data;
bnc691fda62016-08-12 00:43:161448 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011449 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081450 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381451}
1452
bncd16676a2016-07-20 16:23:011453TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381454 HttpRequestInfo request;
1455 request.method = "POST";
1456 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381457
danakj1fd259a02016-04-16 03:17:091458 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161459 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271460
[email protected]ee9410e72010-01-07 01:42:381461 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061462 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381463 };
[email protected]31a2bfe2010-02-09 08:03:391464 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071465 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381466
[email protected]49639fa2011-12-20 23:22:411467 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381468
tfarina42834112016-09-22 13:38:201469 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381471
1472 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011473 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381474}
1475
[email protected]23e482282013-06-14 16:08:021476void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511477 const MockWrite* write_failure,
1478 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421479 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521480 request.method = "GET";
1481 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521482
vishal.b62985ca92015-04-17 08:45:511483 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071484 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271486
[email protected]202965992011-12-07 23:04:511487 // Written data for successfully sending both requests.
1488 MockWrite data1_writes[] = {
1489 MockWrite("GET / HTTP/1.1\r\n"
1490 "Host: www.foo.com\r\n"
1491 "Connection: keep-alive\r\n\r\n"),
1492 MockWrite("GET / HTTP/1.1\r\n"
1493 "Host: www.foo.com\r\n"
1494 "Connection: keep-alive\r\n\r\n")
1495 };
1496
1497 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521498 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351499 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1500 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061501 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521502 };
[email protected]202965992011-12-07 23:04:511503
1504 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491505 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511506 data1_writes[1] = *write_failure;
1507 } else {
1508 ASSERT_TRUE(read_failure);
1509 data1_reads[2] = *read_failure;
1510 }
1511
1512 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1513 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071514 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521515
1516 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351517 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1518 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061519 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521520 };
[email protected]31a2bfe2010-02-09 08:03:391521 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071522 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521523
thestig9d3bb0c2015-01-24 00:49:511524 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521525 "hello", "world"
1526 };
1527
mikecironef22f9812016-10-04 03:40:191528 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521529 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411530 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521531
bnc691fda62016-08-12 00:43:161532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521533
tfarina42834112016-09-22 13:38:201534 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011535 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521536
1537 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011538 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521539
[email protected]58e32bb2013-01-21 18:23:251540 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161541 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251542 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1543 if (i == 0) {
1544 first_socket_log_id = load_timing_info.socket_log_id;
1545 } else {
1546 // The second request should be using a new socket.
1547 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1548 }
1549
bnc691fda62016-08-12 00:43:161550 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521551 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521552
wezca1070932016-05-26 20:30:521553 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471554 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251555 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521556
1557 std::string response_data;
bnc691fda62016-08-12 00:43:161558 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011559 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251560 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521561 }
1562}
[email protected]3d2a59b2008-09-26 19:44:251563
[email protected]a34f61ee2014-03-18 20:59:491564void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1565 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101566 const MockRead* read_failure,
1567 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491568 HttpRequestInfo request;
1569 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101570 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491571
vishal.b62985ca92015-04-17 08:45:511572 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491573 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491575
[email protected]09356c652014-03-25 15:36:101576 SSLSocketDataProvider ssl1(ASYNC, OK);
1577 SSLSocketDataProvider ssl2(ASYNC, OK);
1578 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361579 ssl1.next_proto = kProtoHTTP2;
1580 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101581 }
1582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491584
[email protected]09356c652014-03-25 15:36:101585 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411586 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491587 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411588 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151589 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411590 SpdySerializedFrame spdy_data(
1591 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491592
[email protected]09356c652014-03-25 15:36:101593 // HTTP/1.1 versions of the request and response.
1594 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1595 "Host: www.foo.com\r\n"
1596 "Connection: keep-alive\r\n\r\n";
1597 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1598 const char kHttpData[] = "hello";
1599
1600 std::vector<MockRead> data1_reads;
1601 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491602 if (write_failure) {
1603 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101604 data1_writes.push_back(*write_failure);
1605 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491606 } else {
1607 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101608 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411609 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101610 } else {
1611 data1_writes.push_back(MockWrite(kHttpRequest));
1612 }
1613 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491614 }
1615
[email protected]09356c652014-03-25 15:36:101616 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1617 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491618 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1619
[email protected]09356c652014-03-25 15:36:101620 std::vector<MockRead> data2_reads;
1621 std::vector<MockWrite> data2_writes;
1622
1623 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411624 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101625
bncdf80d44fd2016-07-15 20:27:411626 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1627 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101628 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1629 } else {
1630 data2_writes.push_back(
1631 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1632
1633 data2_reads.push_back(
1634 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1635 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1636 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1637 }
rch8e6c6c42015-05-01 14:05:131638 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1639 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491640 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1641
1642 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591643 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491644 // Wait for the preconnect to complete.
1645 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1646 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101647 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491648
1649 // Make the request.
1650 TestCompletionCallback callback;
1651
bnc691fda62016-08-12 00:43:161652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491653
tfarina42834112016-09-22 13:38:201654 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491656
1657 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011658 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491659
1660 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161661 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101662 TestLoadTimingNotReused(
1663 load_timing_info,
1664 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491665
bnc691fda62016-08-12 00:43:161666 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521667 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491668
wezca1070932016-05-26 20:30:521669 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021670 if (response->was_fetched_via_spdy) {
1671 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1672 } else {
1673 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1674 }
[email protected]a34f61ee2014-03-18 20:59:491675
1676 std::string response_data;
bnc691fda62016-08-12 00:43:161677 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011678 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101679 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491680}
1681
bncd16676a2016-07-20 16:23:011682TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061683 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511684 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1685}
1686
bncd16676a2016-07-20 16:23:011687TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061688 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511689 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251690}
1691
bncd16676a2016-07-20 16:23:011692TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061693 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511694 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251695}
1696
[email protected]d58ceea82014-06-04 10:55:541697// Make sure that on a 408 response (Request Timeout), the request is retried,
1698// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011699TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541700 MockRead read_failure(SYNCHRONOUS,
1701 "HTTP/1.1 408 Request Timeout\r\n"
1702 "Connection: Keep-Alive\r\n"
1703 "Content-Length: 6\r\n\r\n"
1704 "Pickle");
1705 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1706}
1707
bncd16676a2016-07-20 16:23:011708TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491709 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101710 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491711}
1712
bncd16676a2016-07-20 16:23:011713TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491714 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101715 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491716}
1717
bncd16676a2016-07-20 16:23:011718TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491719 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101720 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1721}
1722
bncd16676a2016-07-20 16:23:011723TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101724 MockRead read_failure(ASYNC, OK); // EOF
1725 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1726}
1727
[email protected]d58ceea82014-06-04 10:55:541728// Make sure that on a 408 response (Request Timeout), the request is retried,
1729// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011730TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541731 MockRead read_failure(SYNCHRONOUS,
1732 "HTTP/1.1 408 Request Timeout\r\n"
1733 "Connection: Keep-Alive\r\n"
1734 "Content-Length: 6\r\n\r\n"
1735 "Pickle");
1736 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1737 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1738}
1739
bncd16676a2016-07-20 16:23:011740TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101741 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1742 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1743}
1744
bncd16676a2016-07-20 16:23:011745TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101746 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1747 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1748}
1749
bncd16676a2016-07-20 16:23:011750TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101751 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1752 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1753}
1754
bncd16676a2016-07-20 16:23:011755TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101756 MockRead read_failure(ASYNC, OK); // EOF
1757 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491758}
1759
bncd16676a2016-07-20 16:23:011760TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421761 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251762 request.method = "GET";
bncce36dca22015-04-21 22:11:231763 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251764
danakj1fd259a02016-04-16 03:17:091765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271767
[email protected]3d2a59b2008-09-26 19:44:251768 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061769 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351770 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1771 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061772 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251773 };
[email protected]31a2bfe2010-02-09 08:03:391774 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071775 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251776
[email protected]49639fa2011-12-20 23:22:411777 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251778
tfarina42834112016-09-22 13:38:201779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251781
1782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011783 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591784
1785 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161786 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591787 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251788}
1789
1790// What do various browsers do when the server closes a non-keepalive
1791// connection without sending any response header or body?
1792//
1793// IE7: error page
1794// Safari 3.1.2 (Windows): error page
1795// Firefox 3.0.1: blank page
1796// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421797// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1798// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011799TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251800 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061801 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351802 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1803 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061804 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251805 };
[email protected]31a2bfe2010-02-09 08:03:391806 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1807 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011808 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251809}
[email protected]1826a402014-01-08 15:40:481810
[email protected]7a5378b2012-11-04 03:25:171811// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1812// tests. There was a bug causing HttpNetworkTransaction to hang in the
1813// destructor in such situations.
1814// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011815TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171816 HttpRequestInfo request;
1817 request.method = "GET";
bncce36dca22015-04-21 22:11:231818 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171819
danakj1fd259a02016-04-16 03:17:091820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581821 auto trans =
1822 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171823
1824 MockRead data_reads[] = {
1825 MockRead("HTTP/1.0 200 OK\r\n"),
1826 MockRead("Connection: keep-alive\r\n"),
1827 MockRead("Content-Length: 100\r\n\r\n"),
1828 MockRead("hello"),
1829 MockRead(SYNCHRONOUS, 0),
1830 };
1831 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071832 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171833
1834 TestCompletionCallback callback;
1835
tfarina42834112016-09-22 13:38:201836 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171838
1839 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011840 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171841
1842 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501843 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171844 if (rv == ERR_IO_PENDING)
1845 rv = callback.WaitForResult();
1846 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501847 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011848 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171849
1850 trans.reset();
fdoray92e35a72016-06-10 15:54:551851 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171852 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1853}
1854
bncd16676a2016-07-20 16:23:011855TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171856 HttpRequestInfo request;
1857 request.method = "GET";
bncce36dca22015-04-21 22:11:231858 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171859
danakj1fd259a02016-04-16 03:17:091860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581861 auto trans =
1862 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171863
1864 MockRead data_reads[] = {
1865 MockRead("HTTP/1.0 200 OK\r\n"),
1866 MockRead("Connection: keep-alive\r\n"),
1867 MockRead("Content-Length: 100\r\n\r\n"),
1868 MockRead(SYNCHRONOUS, 0),
1869 };
1870 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171872
1873 TestCompletionCallback callback;
1874
tfarina42834112016-09-22 13:38:201875 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171877
1878 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011879 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171880
1881 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501882 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171883 if (rv == ERR_IO_PENDING)
1884 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011885 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171886
1887 trans.reset();
fdoray92e35a72016-06-10 15:54:551888 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171889 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1890}
1891
[email protected]0b0bf032010-09-21 18:08:501892// Test that we correctly reuse a keep-alive connection after not explicitly
1893// reading the body.
bncd16676a2016-07-20 16:23:011894TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131895 HttpRequestInfo request;
1896 request.method = "GET";
1897 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131898
vishal.b62985ca92015-04-17 08:45:511899 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071900 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091901 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271902
mmenkecc2298e2015-12-07 18:20:181903 const char* request_data =
1904 "GET / HTTP/1.1\r\n"
1905 "Host: www.foo.com\r\n"
1906 "Connection: keep-alive\r\n\r\n";
1907 MockWrite data_writes[] = {
1908 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1909 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1910 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1911 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1912 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1913 };
1914
[email protected]0b0bf032010-09-21 18:08:501915 // Note that because all these reads happen in the same
1916 // StaticSocketDataProvider, it shows that the same socket is being reused for
1917 // all transactions.
mmenkecc2298e2015-12-07 18:20:181918 MockRead data_reads[] = {
1919 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1920 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1921 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1922 MockRead(ASYNC, 7,
1923 "HTTP/1.1 302 Found\r\n"
1924 "Content-Length: 0\r\n\r\n"),
1925 MockRead(ASYNC, 9,
1926 "HTTP/1.1 302 Found\r\n"
1927 "Content-Length: 5\r\n\r\n"
1928 "hello"),
1929 MockRead(ASYNC, 11,
1930 "HTTP/1.1 301 Moved Permanently\r\n"
1931 "Content-Length: 0\r\n\r\n"),
1932 MockRead(ASYNC, 13,
1933 "HTTP/1.1 301 Moved Permanently\r\n"
1934 "Content-Length: 5\r\n\r\n"
1935 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131936
mmenkecc2298e2015-12-07 18:20:181937 // In the next two rounds, IsConnectedAndIdle returns false, due to
1938 // the set_busy_before_sync_reads(true) call, while the
1939 // HttpNetworkTransaction is being shut down, but the socket is still
1940 // reuseable. See http://crbug.com/544255.
1941 MockRead(ASYNC, 15,
1942 "HTTP/1.1 200 Hunky-Dory\r\n"
1943 "Content-Length: 5\r\n\r\n"),
1944 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131945
mmenkecc2298e2015-12-07 18:20:181946 MockRead(ASYNC, 18,
1947 "HTTP/1.1 200 Hunky-Dory\r\n"
1948 "Content-Length: 5\r\n\r\n"
1949 "he"),
1950 MockRead(SYNCHRONOUS, 19, "llo"),
1951
1952 // The body of the final request is actually read.
1953 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1954 MockRead(ASYNC, 22, "hello"),
1955 };
1956 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1957 arraysize(data_writes));
1958 data.set_busy_before_sync_reads(true);
1959 session_deps_.socket_factory->AddSocketDataProvider(&data);
1960
1961 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501962 std::string response_lines[kNumUnreadBodies];
1963
mikecironef22f9812016-10-04 03:40:191964 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181965 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411966 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131967
bnc87dcefc2017-05-25 12:47:581968 auto trans = base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
1969 session.get());
[email protected]fc31d6a42010-06-24 18:05:131970
tfarina42834112016-09-22 13:38:201971 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011972 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131973
[email protected]58e32bb2013-01-21 18:23:251974 LoadTimingInfo load_timing_info;
1975 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1976 if (i == 0) {
1977 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1978 first_socket_log_id = load_timing_info.socket_log_id;
1979 } else {
1980 TestLoadTimingReused(load_timing_info);
1981 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1982 }
1983
[email protected]fc31d6a42010-06-24 18:05:131984 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181985 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131986
mmenkecc2298e2015-12-07 18:20:181987 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501988 response_lines[i] = response->headers->GetStatusLine();
1989
mmenkecc2298e2015-12-07 18:20:181990 // Delete the transaction without reading the response bodies. Then spin
1991 // the message loop, so the response bodies are drained.
1992 trans.reset();
1993 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131994 }
[email protected]0b0bf032010-09-21 18:08:501995
1996 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181997 "HTTP/1.1 204 No Content",
1998 "HTTP/1.1 205 Reset Content",
1999 "HTTP/1.1 304 Not Modified",
2000 "HTTP/1.1 302 Found",
2001 "HTTP/1.1 302 Found",
2002 "HTTP/1.1 301 Moved Permanently",
2003 "HTTP/1.1 301 Moved Permanently",
2004 "HTTP/1.1 200 Hunky-Dory",
2005 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502006 };
2007
mostynb91e0da982015-01-20 19:17:272008 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2009 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502010
2011 for (int i = 0; i < kNumUnreadBodies; ++i)
2012 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2013
[email protected]49639fa2011-12-20 23:22:412014 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202016 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012017 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162018 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182019 ASSERT_TRUE(response);
2020 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502021 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2022 std::string response_data;
bnc691fda62016-08-12 00:43:162023 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012024 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502025 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132026}
2027
mmenke5f94fda2016-06-02 20:54:132028// Sockets that receive extra data after a response is complete should not be
2029// reused.
bncd16676a2016-07-20 16:23:012030TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2032 MockWrite data_writes1[] = {
2033 MockWrite("HEAD / HTTP/1.1\r\n"
2034 "Host: www.borked.com\r\n"
2035 "Connection: keep-alive\r\n\r\n"),
2036 };
2037
2038 MockRead data_reads1[] = {
2039 MockRead("HTTP/1.1 200 OK\r\n"
2040 "Connection: keep-alive\r\n"
2041 "Content-Length: 22\r\n\r\n"
2042 "This server is borked."),
2043 };
2044
2045 MockWrite data_writes2[] = {
2046 MockWrite("GET /foo HTTP/1.1\r\n"
2047 "Host: www.borked.com\r\n"
2048 "Connection: keep-alive\r\n\r\n"),
2049 };
2050
2051 MockRead data_reads2[] = {
2052 MockRead("HTTP/1.1 200 OK\r\n"
2053 "Content-Length: 3\r\n\r\n"
2054 "foo"),
2055 };
2056 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2057 data_writes1, arraysize(data_writes1));
2058 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2059 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2060 data_writes2, arraysize(data_writes2));
2061 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2062
2063 TestCompletionCallback callback;
2064 HttpRequestInfo request1;
2065 request1.method = "HEAD";
2066 request1.url = GURL("http://www.borked.com/");
2067
bnc87dcefc2017-05-25 12:47:582068 auto trans1 =
2069 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202070 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012071 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132072
2073 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2074 ASSERT_TRUE(response1);
2075 ASSERT_TRUE(response1->headers);
2076 EXPECT_EQ(200, response1->headers->response_code());
2077 EXPECT_TRUE(response1->headers->IsKeepAlive());
2078
2079 std::string response_data1;
robpercival214763f2016-07-01 23:27:012080 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132081 EXPECT_EQ("", response_data1);
2082 // Deleting the transaction attempts to release the socket back into the
2083 // socket pool.
2084 trans1.reset();
2085
2086 HttpRequestInfo request2;
2087 request2.method = "GET";
2088 request2.url = GURL("http://www.borked.com/foo");
2089
bnc87dcefc2017-05-25 12:47:582090 auto trans2 =
2091 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202092 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012093 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132094
2095 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2096 ASSERT_TRUE(response2);
2097 ASSERT_TRUE(response2->headers);
2098 EXPECT_EQ(200, response2->headers->response_code());
2099
2100 std::string response_data2;
robpercival214763f2016-07-01 23:27:012101 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132102 EXPECT_EQ("foo", response_data2);
2103}
2104
bncd16676a2016-07-20 16:23:012105TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2107 MockWrite data_writes1[] = {
2108 MockWrite("GET / HTTP/1.1\r\n"
2109 "Host: www.borked.com\r\n"
2110 "Connection: keep-alive\r\n\r\n"),
2111 };
2112
2113 MockRead data_reads1[] = {
2114 MockRead("HTTP/1.1 200 OK\r\n"
2115 "Connection: keep-alive\r\n"
2116 "Content-Length: 22\r\n\r\n"
2117 "This server is borked."
2118 "Bonus data!"),
2119 };
2120
2121 MockWrite data_writes2[] = {
2122 MockWrite("GET /foo HTTP/1.1\r\n"
2123 "Host: www.borked.com\r\n"
2124 "Connection: keep-alive\r\n\r\n"),
2125 };
2126
2127 MockRead data_reads2[] = {
2128 MockRead("HTTP/1.1 200 OK\r\n"
2129 "Content-Length: 3\r\n\r\n"
2130 "foo"),
2131 };
2132 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2133 data_writes1, arraysize(data_writes1));
2134 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2135 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2136 data_writes2, arraysize(data_writes2));
2137 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2138
2139 TestCompletionCallback callback;
2140 HttpRequestInfo request1;
2141 request1.method = "GET";
2142 request1.url = GURL("http://www.borked.com/");
2143
bnc87dcefc2017-05-25 12:47:582144 auto trans1 =
2145 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202146 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012147 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132148
2149 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2150 ASSERT_TRUE(response1);
2151 ASSERT_TRUE(response1->headers);
2152 EXPECT_EQ(200, response1->headers->response_code());
2153 EXPECT_TRUE(response1->headers->IsKeepAlive());
2154
2155 std::string response_data1;
robpercival214763f2016-07-01 23:27:012156 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132157 EXPECT_EQ("This server is borked.", response_data1);
2158 // Deleting the transaction attempts to release the socket back into the
2159 // socket pool.
2160 trans1.reset();
2161
2162 HttpRequestInfo request2;
2163 request2.method = "GET";
2164 request2.url = GURL("http://www.borked.com/foo");
2165
bnc87dcefc2017-05-25 12:47:582166 auto trans2 =
2167 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202168 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012169 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132170
2171 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2172 ASSERT_TRUE(response2);
2173 ASSERT_TRUE(response2->headers);
2174 EXPECT_EQ(200, response2->headers->response_code());
2175
2176 std::string response_data2;
robpercival214763f2016-07-01 23:27:012177 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132178 EXPECT_EQ("foo", response_data2);
2179}
2180
bncd16676a2016-07-20 16:23:012181TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132182 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2183 MockWrite data_writes1[] = {
2184 MockWrite("GET / HTTP/1.1\r\n"
2185 "Host: www.borked.com\r\n"
2186 "Connection: keep-alive\r\n\r\n"),
2187 };
2188
2189 MockRead data_reads1[] = {
2190 MockRead("HTTP/1.1 200 OK\r\n"
2191 "Connection: keep-alive\r\n"
2192 "Transfer-Encoding: chunked\r\n\r\n"),
2193 MockRead("16\r\nThis server is borked.\r\n"),
2194 MockRead("0\r\n\r\nBonus data!"),
2195 };
2196
2197 MockWrite data_writes2[] = {
2198 MockWrite("GET /foo HTTP/1.1\r\n"
2199 "Host: www.borked.com\r\n"
2200 "Connection: keep-alive\r\n\r\n"),
2201 };
2202
2203 MockRead data_reads2[] = {
2204 MockRead("HTTP/1.1 200 OK\r\n"
2205 "Content-Length: 3\r\n\r\n"
2206 "foo"),
2207 };
2208 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2209 data_writes1, arraysize(data_writes1));
2210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2211 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2212 data_writes2, arraysize(data_writes2));
2213 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2214
2215 TestCompletionCallback callback;
2216 HttpRequestInfo request1;
2217 request1.method = "GET";
2218 request1.url = GURL("http://www.borked.com/");
2219
bnc87dcefc2017-05-25 12:47:582220 auto trans1 =
2221 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202222 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012223 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132224
2225 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2226 ASSERT_TRUE(response1);
2227 ASSERT_TRUE(response1->headers);
2228 EXPECT_EQ(200, response1->headers->response_code());
2229 EXPECT_TRUE(response1->headers->IsKeepAlive());
2230
2231 std::string response_data1;
robpercival214763f2016-07-01 23:27:012232 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132233 EXPECT_EQ("This server is borked.", response_data1);
2234 // Deleting the transaction attempts to release the socket back into the
2235 // socket pool.
2236 trans1.reset();
2237
2238 HttpRequestInfo request2;
2239 request2.method = "GET";
2240 request2.url = GURL("http://www.borked.com/foo");
2241
bnc87dcefc2017-05-25 12:47:582242 auto trans2 =
2243 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202244 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012245 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132246
2247 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2248 ASSERT_TRUE(response2);
2249 ASSERT_TRUE(response2->headers);
2250 EXPECT_EQ(200, response2->headers->response_code());
2251
2252 std::string response_data2;
robpercival214763f2016-07-01 23:27:012253 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132254 EXPECT_EQ("foo", response_data2);
2255}
2256
2257// This is a little different from the others - it tests the case that the
2258// HttpStreamParser doesn't know if there's extra data on a socket or not when
2259// the HttpNetworkTransaction is torn down, because the response body hasn't
2260// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012261TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2263 MockWrite data_writes1[] = {
2264 MockWrite("GET / HTTP/1.1\r\n"
2265 "Host: www.borked.com\r\n"
2266 "Connection: keep-alive\r\n\r\n"),
2267 };
2268
2269 MockRead data_reads1[] = {
2270 MockRead("HTTP/1.1 200 OK\r\n"
2271 "Connection: keep-alive\r\n"
2272 "Transfer-Encoding: chunked\r\n\r\n"),
2273 MockRead("16\r\nThis server is borked.\r\n"),
2274 MockRead("0\r\n\r\nBonus data!"),
2275 };
2276 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2277 data_writes1, arraysize(data_writes1));
2278 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2279
2280 TestCompletionCallback callback;
2281 HttpRequestInfo request1;
2282 request1.method = "GET";
2283 request1.url = GURL("http://www.borked.com/");
2284
bnc87dcefc2017-05-25 12:47:582285 auto trans =
2286 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2287 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012288 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132289
bnc87dcefc2017-05-25 12:47:582290 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132291 ASSERT_TRUE(response1);
2292 ASSERT_TRUE(response1->headers);
2293 EXPECT_EQ(200, response1->headers->response_code());
2294 EXPECT_TRUE(response1->headers->IsKeepAlive());
2295
2296 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2297 // response body.
bnc87dcefc2017-05-25 12:47:582298 trans.reset();
mmenke5f94fda2016-06-02 20:54:132299
2300 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2301 // socket can't be reused, rather than returning it to the socket pool.
2302 base::RunLoop().RunUntilIdle();
2303
2304 // There should be no idle sockets in the pool.
2305 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2306}
2307
[email protected]038e9a32008-10-08 22:40:162308// Test the request-challenge-retry sequence for basic auth.
2309// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012310TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422311 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162312 request.method = "GET";
bncce36dca22015-04-21 22:11:232313 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162314
vishal.b62985ca92015-04-17 08:45:512315 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072316 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162318 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272319
[email protected]f9ee6b52008-11-08 06:46:232320 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232321 MockWrite(
2322 "GET / HTTP/1.1\r\n"
2323 "Host: www.example.org\r\n"
2324 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232325 };
2326
[email protected]038e9a32008-10-08 22:40:162327 MockRead data_reads1[] = {
2328 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2329 // Give a couple authenticate options (only the middle one is actually
2330 // supported).
[email protected]22927ad2009-09-21 19:56:192331 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162332 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2333 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2334 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2335 // Large content-length -- won't matter, as connection will be reset.
2336 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062337 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162338 };
2339
2340 // After calling trans->RestartWithAuth(), this is the request we should
2341 // be issuing -- the final header line contains the credentials.
2342 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232343 MockWrite(
2344 "GET / HTTP/1.1\r\n"
2345 "Host: www.example.org\r\n"
2346 "Connection: keep-alive\r\n"
2347 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162348 };
2349
2350 // Lastly, the server responds with the actual content.
2351 MockRead data_reads2[] = {
2352 MockRead("HTTP/1.0 200 OK\r\n"),
2353 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2354 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062355 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162356 };
2357
[email protected]31a2bfe2010-02-09 08:03:392358 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2359 data_writes1, arraysize(data_writes1));
2360 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2361 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072362 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2363 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162364
[email protected]49639fa2011-12-20 23:22:412365 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162366
tfarina42834112016-09-22 13:38:202367 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162369
2370 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012371 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162372
[email protected]58e32bb2013-01-21 18:23:252373 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162374 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252375 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2376
sclittlefb249892015-09-10 21:33:222377 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162378 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222379 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162380 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192381
bnc691fda62016-08-12 00:43:162382 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522383 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042384 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162385
[email protected]49639fa2011-12-20 23:22:412386 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162387
bnc691fda62016-08-12 00:43:162388 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162390
2391 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012392 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162393
[email protected]58e32bb2013-01-21 18:23:252394 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162395 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252396 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2397 // The load timing after restart should have a new socket ID, and times after
2398 // those of the first load timing.
2399 EXPECT_LE(load_timing_info1.receive_headers_end,
2400 load_timing_info2.connect_timing.connect_start);
2401 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2402
sclittlefb249892015-09-10 21:33:222403 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162404 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222405 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162406 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192407
bnc691fda62016-08-12 00:43:162408 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522409 ASSERT_TRUE(response);
2410 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162411 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162412}
2413
ttuttled9dbc652015-09-29 20:00:592414// Test the request-challenge-retry sequence for basic auth.
2415// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012416TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592417 HttpRequestInfo request;
2418 request.method = "GET";
2419 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592420
2421 TestNetLog log;
2422 MockHostResolver* resolver = new MockHostResolver();
2423 session_deps_.net_log = &log;
2424 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092425 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162426 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592427
2428 resolver->rules()->ClearRules();
2429 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2430
2431 MockWrite data_writes1[] = {
2432 MockWrite("GET / HTTP/1.1\r\n"
2433 "Host: www.example.org\r\n"
2434 "Connection: keep-alive\r\n\r\n"),
2435 };
2436
2437 MockRead data_reads1[] = {
2438 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2439 // Give a couple authenticate options (only the middle one is actually
2440 // supported).
2441 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2442 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2443 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2444 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2445 // Large content-length -- won't matter, as connection will be reset.
2446 MockRead("Content-Length: 10000\r\n\r\n"),
2447 MockRead(SYNCHRONOUS, ERR_FAILED),
2448 };
2449
2450 // After calling trans->RestartWithAuth(), this is the request we should
2451 // be issuing -- the final header line contains the credentials.
2452 MockWrite data_writes2[] = {
2453 MockWrite("GET / HTTP/1.1\r\n"
2454 "Host: www.example.org\r\n"
2455 "Connection: keep-alive\r\n"
2456 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2457 };
2458
2459 // Lastly, the server responds with the actual content.
2460 MockRead data_reads2[] = {
2461 MockRead("HTTP/1.0 200 OK\r\n"),
2462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2463 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2464 };
2465
2466 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2467 data_writes1, arraysize(data_writes1));
2468 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2469 data_writes2, arraysize(data_writes2));
2470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2471 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2472
2473 TestCompletionCallback callback1;
2474
bnc691fda62016-08-12 00:43:162475 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202476 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592477
2478 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162479 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592480 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2481
2482 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162483 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592484 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162485 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592486
bnc691fda62016-08-12 00:43:162487 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592488 ASSERT_TRUE(response);
2489 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2490
2491 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162492 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592493 ASSERT_FALSE(endpoint.address().empty());
2494 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2495
2496 resolver->rules()->ClearRules();
2497 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2498
2499 TestCompletionCallback callback2;
2500
bnc691fda62016-08-12 00:43:162501 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592502 AuthCredentials(kFoo, kBar), callback2.callback())));
2503
2504 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162505 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592506 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2507 // The load timing after restart should have a new socket ID, and times after
2508 // those of the first load timing.
2509 EXPECT_LE(load_timing_info1.receive_headers_end,
2510 load_timing_info2.connect_timing.connect_start);
2511 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2512
2513 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162514 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592515 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162516 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592517
bnc691fda62016-08-12 00:43:162518 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592519 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522520 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592521 EXPECT_EQ(100, response->headers->GetContentLength());
2522
bnc691fda62016-08-12 00:43:162523 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592524 ASSERT_FALSE(endpoint.address().empty());
2525 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2526}
2527
bncd16676a2016-07-20 16:23:012528TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462529 HttpRequestInfo request;
2530 request.method = "GET";
bncce36dca22015-04-21 22:11:232531 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292532 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462533
danakj1fd259a02016-04-16 03:17:092534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162535 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272536
[email protected]861fcd52009-08-26 02:33:462537 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232538 MockWrite(
2539 "GET / HTTP/1.1\r\n"
2540 "Host: www.example.org\r\n"
2541 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462542 };
2543
2544 MockRead data_reads[] = {
2545 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2546 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2548 // Large content-length -- won't matter, as connection will be reset.
2549 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062550 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462551 };
2552
[email protected]31a2bfe2010-02-09 08:03:392553 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2554 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072555 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412556 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462557
tfarina42834112016-09-22 13:38:202558 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462560
2561 rv = callback.WaitForResult();
2562 EXPECT_EQ(0, rv);
2563
sclittlefb249892015-09-10 21:33:222564 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162565 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222566 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162567 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192568
bnc691fda62016-08-12 00:43:162569 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522570 ASSERT_TRUE(response);
2571 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462572}
2573
[email protected]2d2697f92009-02-18 21:00:322574// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2575// connection.
bncd16676a2016-07-20 16:23:012576TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182577 // On the second pass, the body read of the auth challenge is synchronous, so
2578 // IsConnectedAndIdle returns false. The socket should still be drained and
2579 // reused. See http://crbug.com/544255.
2580 for (int i = 0; i < 2; ++i) {
2581 HttpRequestInfo request;
2582 request.method = "GET";
2583 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322584
mmenkecc2298e2015-12-07 18:20:182585 TestNetLog log;
2586 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272588
mmenkecc2298e2015-12-07 18:20:182589 MockWrite data_writes[] = {
2590 MockWrite(ASYNC, 0,
2591 "GET / HTTP/1.1\r\n"
2592 "Host: www.example.org\r\n"
2593 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322594
bnc691fda62016-08-12 00:43:162595 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182596 // be issuing -- the final header line contains the credentials.
2597 MockWrite(ASYNC, 6,
2598 "GET / HTTP/1.1\r\n"
2599 "Host: www.example.org\r\n"
2600 "Connection: keep-alive\r\n"
2601 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2602 };
[email protected]2d2697f92009-02-18 21:00:322603
mmenkecc2298e2015-12-07 18:20:182604 MockRead data_reads[] = {
2605 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2606 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2607 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2608 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2609 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322610
mmenkecc2298e2015-12-07 18:20:182611 // Lastly, the server responds with the actual content.
2612 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2613 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2614 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2615 MockRead(ASYNC, 10, "Hello"),
2616 };
[email protected]2d2697f92009-02-18 21:00:322617
mmenkecc2298e2015-12-07 18:20:182618 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2619 arraysize(data_writes));
2620 data.set_busy_before_sync_reads(true);
2621 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462622
mmenkecc2298e2015-12-07 18:20:182623 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322624
bnc691fda62016-08-12 00:43:162625 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202626 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012627 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322628
mmenkecc2298e2015-12-07 18:20:182629 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162630 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182631 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322632
bnc691fda62016-08-12 00:43:162633 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182634 ASSERT_TRUE(response);
2635 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322636
mmenkecc2298e2015-12-07 18:20:182637 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252638
bnc691fda62016-08-12 00:43:162639 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2640 callback2.callback());
robpercival214763f2016-07-01 23:27:012641 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322642
mmenkecc2298e2015-12-07 18:20:182643 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162644 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182645 TestLoadTimingReused(load_timing_info2);
2646 // The load timing after restart should have the same socket ID, and times
2647 // those of the first load timing.
2648 EXPECT_LE(load_timing_info1.receive_headers_end,
2649 load_timing_info2.send_start);
2650 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322651
bnc691fda62016-08-12 00:43:162652 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182653 ASSERT_TRUE(response);
2654 EXPECT_FALSE(response->auth_challenge);
2655 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322656
mmenkecc2298e2015-12-07 18:20:182657 std::string response_data;
bnc691fda62016-08-12 00:43:162658 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322659
mmenkecc2298e2015-12-07 18:20:182660 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162661 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182662 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162663 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182664 }
[email protected]2d2697f92009-02-18 21:00:322665}
2666
2667// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2668// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012669TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422670 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322671 request.method = "GET";
bncce36dca22015-04-21 22:11:232672 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322673
danakj1fd259a02016-04-16 03:17:092674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272675
[email protected]2d2697f92009-02-18 21:00:322676 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162677 MockWrite("GET / HTTP/1.1\r\n"
2678 "Host: www.example.org\r\n"
2679 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322680
bnc691fda62016-08-12 00:43:162681 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232682 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162683 MockWrite("GET / HTTP/1.1\r\n"
2684 "Host: www.example.org\r\n"
2685 "Connection: keep-alive\r\n"
2686 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322687 };
2688
[email protected]2d2697f92009-02-18 21:00:322689 MockRead data_reads1[] = {
2690 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2691 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312692 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322693
2694 // Lastly, the server responds with the actual content.
2695 MockRead("HTTP/1.1 200 OK\r\n"),
2696 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502697 MockRead("Content-Length: 5\r\n\r\n"),
2698 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322699 };
2700
[email protected]2d0a4f92011-05-05 16:38:462701 // An incorrect reconnect would cause this to be read.
2702 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062703 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462704 };
2705
[email protected]31a2bfe2010-02-09 08:03:392706 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2707 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462708 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2709 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072710 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2711 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322712
[email protected]49639fa2011-12-20 23:22:412713 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322714
bnc691fda62016-08-12 00:43:162715 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202716 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322718
2719 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012720 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322721
bnc691fda62016-08-12 00:43:162722 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522723 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042724 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322725
[email protected]49639fa2011-12-20 23:22:412726 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322727
bnc691fda62016-08-12 00:43:162728 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322730
2731 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012732 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322733
bnc691fda62016-08-12 00:43:162734 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522735 ASSERT_TRUE(response);
2736 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502737 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322738}
2739
2740// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2741// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012742TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422743 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322744 request.method = "GET";
bncce36dca22015-04-21 22:11:232745 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322746
danakj1fd259a02016-04-16 03:17:092747 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272748
[email protected]2d2697f92009-02-18 21:00:322749 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162750 MockWrite("GET / HTTP/1.1\r\n"
2751 "Host: www.example.org\r\n"
2752 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322753
bnc691fda62016-08-12 00:43:162754 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232755 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162756 MockWrite("GET / HTTP/1.1\r\n"
2757 "Host: www.example.org\r\n"
2758 "Connection: keep-alive\r\n"
2759 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322760 };
2761
2762 // Respond with 5 kb of response body.
2763 std::string large_body_string("Unauthorized");
2764 large_body_string.append(5 * 1024, ' ');
2765 large_body_string.append("\r\n");
2766
2767 MockRead data_reads1[] = {
2768 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2769 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2770 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2771 // 5134 = 12 + 5 * 1024 + 2
2772 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062773 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322774
2775 // Lastly, the server responds with the actual content.
2776 MockRead("HTTP/1.1 200 OK\r\n"),
2777 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502778 MockRead("Content-Length: 5\r\n\r\n"),
2779 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322780 };
2781
[email protected]2d0a4f92011-05-05 16:38:462782 // An incorrect reconnect would cause this to be read.
2783 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062784 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462785 };
2786
[email protected]31a2bfe2010-02-09 08:03:392787 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2788 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462789 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2790 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2792 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322793
[email protected]49639fa2011-12-20 23:22:412794 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322795
bnc691fda62016-08-12 00:43:162796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202797 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322799
2800 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012801 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322802
bnc691fda62016-08-12 00:43:162803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522804 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042805 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322806
[email protected]49639fa2011-12-20 23:22:412807 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322808
bnc691fda62016-08-12 00:43:162809 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322811
2812 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012813 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322814
bnc691fda62016-08-12 00:43:162815 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522816 ASSERT_TRUE(response);
2817 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502818 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322819}
2820
2821// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312822// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012823TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312824 HttpRequestInfo request;
2825 request.method = "GET";
bncce36dca22015-04-21 22:11:232826 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312827
danakj1fd259a02016-04-16 03:17:092828 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272829
[email protected]11203f012009-11-12 23:02:312830 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232831 MockWrite(
2832 "GET / HTTP/1.1\r\n"
2833 "Host: www.example.org\r\n"
2834 "Connection: keep-alive\r\n\r\n"),
2835 // This simulates the seemingly successful write to a closed connection
2836 // if the bug is not fixed.
2837 MockWrite(
2838 "GET / HTTP/1.1\r\n"
2839 "Host: www.example.org\r\n"
2840 "Connection: keep-alive\r\n"
2841 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312842 };
2843
2844 MockRead data_reads1[] = {
2845 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2846 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2847 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2848 MockRead("Content-Length: 14\r\n\r\n"),
2849 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062850 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312851 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062852 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312853 };
2854
bnc691fda62016-08-12 00:43:162855 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312856 // be issuing -- the final header line contains the credentials.
2857 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232858 MockWrite(
2859 "GET / HTTP/1.1\r\n"
2860 "Host: www.example.org\r\n"
2861 "Connection: keep-alive\r\n"
2862 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312863 };
2864
2865 // Lastly, the server responds with the actual content.
2866 MockRead data_reads2[] = {
2867 MockRead("HTTP/1.1 200 OK\r\n"),
2868 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502869 MockRead("Content-Length: 5\r\n\r\n"),
2870 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312871 };
2872
[email protected]31a2bfe2010-02-09 08:03:392873 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2874 data_writes1, arraysize(data_writes1));
2875 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2876 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2878 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312879
[email protected]49639fa2011-12-20 23:22:412880 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312881
bnc691fda62016-08-12 00:43:162882 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202883 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312885
2886 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012887 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312888
bnc691fda62016-08-12 00:43:162889 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522890 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042891 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312892
[email protected]49639fa2011-12-20 23:22:412893 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312894
bnc691fda62016-08-12 00:43:162895 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312897
2898 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012899 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312900
bnc691fda62016-08-12 00:43:162901 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522902 ASSERT_TRUE(response);
2903 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502904 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312905}
2906
[email protected]394816e92010-08-03 07:38:592907// Test the request-challenge-retry sequence for basic auth, over a connection
2908// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012909TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012910 HttpRequestInfo request;
2911 request.method = "GET";
bncce36dca22015-04-21 22:11:232912 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012913 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292914 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012915
2916 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032917 session_deps_.proxy_service =
2918 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512919 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012920 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012922
2923 // Since we have proxy, should try to establish tunnel.
2924 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542925 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172926 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542927 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012928 };
2929
mmenkee71e15332015-10-07 16:39:542930 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012931 // connection.
2932 MockRead data_reads1[] = {
2933 // No credentials.
2934 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2935 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542936 };
ttuttle34f63b52015-03-05 04:33:012937
mmenkee71e15332015-10-07 16:39:542938 // Since the first connection couldn't be reused, need to establish another
2939 // once given credentials.
2940 MockWrite data_writes2[] = {
2941 // After calling trans->RestartWithAuth(), this is the request we should
2942 // be issuing -- the final header line contains the credentials.
2943 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172944 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542945 "Proxy-Connection: keep-alive\r\n"
2946 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2947
2948 MockWrite("GET / HTTP/1.1\r\n"
2949 "Host: www.example.org\r\n"
2950 "Connection: keep-alive\r\n\r\n"),
2951 };
2952
2953 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012954 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2955
2956 MockRead("HTTP/1.1 200 OK\r\n"),
2957 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2958 MockRead("Content-Length: 5\r\n\r\n"),
2959 MockRead(SYNCHRONOUS, "hello"),
2960 };
2961
2962 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2963 data_writes1, arraysize(data_writes1));
2964 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542965 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2966 data_writes2, arraysize(data_writes2));
2967 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012968 SSLSocketDataProvider ssl(ASYNC, OK);
2969 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2970
2971 TestCompletionCallback callback1;
2972
bnc87dcefc2017-05-25 12:47:582973 auto trans =
2974 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:012975
2976 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012978
2979 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012980 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462981 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012982 log.GetEntries(&entries);
2983 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002984 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2985 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012986 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002987 entries, pos,
2988 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2989 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012990
2991 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522992 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012993 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522994 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012995 EXPECT_EQ(407, response->headers->response_code());
2996 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2997 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2998
2999 LoadTimingInfo load_timing_info;
3000 // CONNECT requests and responses are handled at the connect job level, so
3001 // the transaction does not yet have a connection.
3002 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3003
3004 TestCompletionCallback callback2;
3005
3006 rv =
3007 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013009
3010 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013011 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013012
3013 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523014 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013015
3016 EXPECT_TRUE(response->headers->IsKeepAlive());
3017 EXPECT_EQ(200, response->headers->response_code());
3018 EXPECT_EQ(5, response->headers->GetContentLength());
3019 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3020
3021 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523022 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013023
3024 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3025 TestLoadTimingNotReusedWithPac(load_timing_info,
3026 CONNECT_TIMING_HAS_SSL_TIMES);
3027
3028 trans.reset();
3029 session->CloseAllConnections();
3030}
3031
3032// Test the request-challenge-retry sequence for basic auth, over a connection
3033// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013034TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593035 HttpRequestInfo request;
3036 request.method = "GET";
bncce36dca22015-04-21 22:11:233037 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593038 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293039 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593040
[email protected]cb9bf6ca2011-01-28 13:15:273041 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033042 session_deps_.proxy_service =
3043 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513044 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073045 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093046 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273047
[email protected]394816e92010-08-03 07:38:593048 // Since we have proxy, should try to establish tunnel.
3049 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543050 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173051 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543052 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113053 };
3054
mmenkee71e15332015-10-07 16:39:543055 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083056 // connection.
3057 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543058 // No credentials.
3059 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3060 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3061 MockRead("Proxy-Connection: close\r\n\r\n"),
3062 };
mmenkee0b5c882015-08-26 20:29:113063
mmenkee71e15332015-10-07 16:39:543064 MockWrite data_writes2[] = {
3065 // After calling trans->RestartWithAuth(), this is the request we should
3066 // be issuing -- the final header line contains the credentials.
3067 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173068 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543069 "Proxy-Connection: keep-alive\r\n"
3070 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083071
mmenkee71e15332015-10-07 16:39:543072 MockWrite("GET / HTTP/1.1\r\n"
3073 "Host: www.example.org\r\n"
3074 "Connection: keep-alive\r\n\r\n"),
3075 };
3076
3077 MockRead data_reads2[] = {
3078 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3079
3080 MockRead("HTTP/1.1 200 OK\r\n"),
3081 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3082 MockRead("Content-Length: 5\r\n\r\n"),
3083 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593084 };
3085
3086 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3087 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073088 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543089 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3090 data_writes2, arraysize(data_writes2));
3091 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063092 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593094
[email protected]49639fa2011-12-20 23:22:413095 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593096
bnc87dcefc2017-05-25 12:47:583097 auto trans =
3098 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503099
[email protected]49639fa2011-12-20 23:22:413100 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013101 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593102
3103 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013104 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463105 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403106 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593107 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003108 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3109 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593110 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403111 entries, pos,
mikecirone8b85c432016-09-08 19:11:003112 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3113 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593114
3115 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523116 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013117 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523118 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593119 EXPECT_EQ(407, response->headers->response_code());
3120 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043121 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593122
[email protected]029c83b62013-01-24 05:28:203123 LoadTimingInfo load_timing_info;
3124 // CONNECT requests and responses are handled at the connect job level, so
3125 // the transaction does not yet have a connection.
3126 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3127
[email protected]49639fa2011-12-20 23:22:413128 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593129
[email protected]49639fa2011-12-20 23:22:413130 rv = trans->RestartWithAuth(
3131 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593133
3134 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013135 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593136
3137 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523138 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593139
3140 EXPECT_TRUE(response->headers->IsKeepAlive());
3141 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503142 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593143 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3144
3145 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523146 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503147
[email protected]029c83b62013-01-24 05:28:203148 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3149 TestLoadTimingNotReusedWithPac(load_timing_info,
3150 CONNECT_TIMING_HAS_SSL_TIMES);
3151
[email protected]0b0bf032010-09-21 18:08:503152 trans.reset();
[email protected]102e27c2011-02-23 01:01:313153 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593154}
3155
[email protected]11203f012009-11-12 23:02:313156// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013157// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013158TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233159 // On the second pass, the body read of the auth challenge is synchronous, so
3160 // IsConnectedAndIdle returns false. The socket should still be drained and
3161 // reused. See http://crbug.com/544255.
3162 for (int i = 0; i < 2; ++i) {
3163 HttpRequestInfo request;
3164 request.method = "GET";
3165 request.url = GURL("https://www.example.org/");
3166 // Ensure that proxy authentication is attempted even
3167 // when the no authentication data flag is set.
3168 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013169
mmenked39192ee2015-12-09 00:57:233170 // Configure against proxy server "myproxy:70".
3171 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3172 BoundTestNetLog log;
3173 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013175
bnc691fda62016-08-12 00:43:163176 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013177
mmenked39192ee2015-12-09 00:57:233178 // Since we have proxy, should try to establish tunnel.
3179 MockWrite data_writes1[] = {
3180 MockWrite(ASYNC, 0,
3181 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3182 "Host: www.example.org:443\r\n"
3183 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013184
bnc691fda62016-08-12 00:43:163185 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233186 // be issuing -- the final header line contains the credentials.
3187 MockWrite(ASYNC, 3,
3188 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3189 "Host: www.example.org:443\r\n"
3190 "Proxy-Connection: keep-alive\r\n"
3191 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3192 };
ttuttle34f63b52015-03-05 04:33:013193
mmenked39192ee2015-12-09 00:57:233194 // The proxy responds to the connect with a 407, using a persistent
3195 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3196 MockRead data_reads1[] = {
3197 // No credentials.
3198 MockRead(ASYNC, 1,
3199 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3200 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3201 "Proxy-Connection: keep-alive\r\n"
3202 "Content-Length: 10\r\n\r\n"),
3203 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013204
mmenked39192ee2015-12-09 00:57:233205 // Wrong credentials (wrong password).
3206 MockRead(ASYNC, 4,
3207 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3208 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3209 "Proxy-Connection: keep-alive\r\n"
3210 "Content-Length: 10\r\n\r\n"),
3211 // No response body because the test stops reading here.
3212 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3213 };
ttuttle34f63b52015-03-05 04:33:013214
mmenked39192ee2015-12-09 00:57:233215 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3216 arraysize(data_writes1));
3217 data1.set_busy_before_sync_reads(true);
3218 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013219
mmenked39192ee2015-12-09 00:57:233220 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013221
bnc691fda62016-08-12 00:43:163222 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013223 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013224
mmenked39192ee2015-12-09 00:57:233225 TestNetLogEntry::List entries;
3226 log.GetEntries(&entries);
3227 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003228 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3229 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233230 ExpectLogContainsSomewhere(
3231 entries, pos,
mikecirone8b85c432016-09-08 19:11:003232 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3233 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013234
bnc691fda62016-08-12 00:43:163235 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233236 ASSERT_TRUE(response);
3237 ASSERT_TRUE(response->headers);
3238 EXPECT_TRUE(response->headers->IsKeepAlive());
3239 EXPECT_EQ(407, response->headers->response_code());
3240 EXPECT_EQ(10, response->headers->GetContentLength());
3241 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3242 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013243
mmenked39192ee2015-12-09 00:57:233244 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013245
mmenked39192ee2015-12-09 00:57:233246 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163247 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3248 callback2.callback());
robpercival214763f2016-07-01 23:27:013249 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013250
bnc691fda62016-08-12 00:43:163251 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233252 ASSERT_TRUE(response);
3253 ASSERT_TRUE(response->headers);
3254 EXPECT_TRUE(response->headers->IsKeepAlive());
3255 EXPECT_EQ(407, response->headers->response_code());
3256 EXPECT_EQ(10, response->headers->GetContentLength());
3257 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3258 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013259
mmenked39192ee2015-12-09 00:57:233260 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3261 // out of scope.
3262 session->CloseAllConnections();
3263 }
ttuttle34f63b52015-03-05 04:33:013264}
3265
3266// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3267// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013268TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233269 // On the second pass, the body read of the auth challenge is synchronous, so
3270 // IsConnectedAndIdle returns false. The socket should still be drained and
3271 // reused. See http://crbug.com/544255.
3272 for (int i = 0; i < 2; ++i) {
3273 HttpRequestInfo request;
3274 request.method = "GET";
3275 request.url = GURL("https://www.example.org/");
3276 // Ensure that proxy authentication is attempted even
3277 // when the no authentication data flag is set.
3278 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3279
3280 // Configure against proxy server "myproxy:70".
3281 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3282 BoundTestNetLog log;
3283 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233285
bnc691fda62016-08-12 00:43:163286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233287
3288 // Since we have proxy, should try to establish tunnel.
3289 MockWrite data_writes1[] = {
3290 MockWrite(ASYNC, 0,
3291 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3292 "Host: www.example.org:443\r\n"
3293 "Proxy-Connection: keep-alive\r\n\r\n"),
3294
bnc691fda62016-08-12 00:43:163295 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233296 // be issuing -- the final header line contains the credentials.
3297 MockWrite(ASYNC, 3,
3298 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3299 "Host: www.example.org:443\r\n"
3300 "Proxy-Connection: keep-alive\r\n"
3301 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3302 };
3303
3304 // The proxy responds to the connect with a 407, using a persistent
3305 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3306 MockRead data_reads1[] = {
3307 // No credentials.
3308 MockRead(ASYNC, 1,
3309 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3310 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3311 "Content-Length: 10\r\n\r\n"),
3312 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3313
3314 // Wrong credentials (wrong password).
3315 MockRead(ASYNC, 4,
3316 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3317 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3318 "Content-Length: 10\r\n\r\n"),
3319 // No response body because the test stops reading here.
3320 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3321 };
3322
3323 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3324 arraysize(data_writes1));
3325 data1.set_busy_before_sync_reads(true);
3326 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3327
3328 TestCompletionCallback callback1;
3329
bnc691fda62016-08-12 00:43:163330 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013331 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233332
3333 TestNetLogEntry::List entries;
3334 log.GetEntries(&entries);
3335 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003336 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3337 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233338 ExpectLogContainsSomewhere(
3339 entries, pos,
mikecirone8b85c432016-09-08 19:11:003340 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3341 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233342
bnc691fda62016-08-12 00:43:163343 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233344 ASSERT_TRUE(response);
3345 ASSERT_TRUE(response->headers);
3346 EXPECT_TRUE(response->headers->IsKeepAlive());
3347 EXPECT_EQ(407, response->headers->response_code());
3348 EXPECT_EQ(10, response->headers->GetContentLength());
3349 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3350 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3351
3352 TestCompletionCallback callback2;
3353
3354 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163355 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3356 callback2.callback());
robpercival214763f2016-07-01 23:27:013357 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233358
bnc691fda62016-08-12 00:43:163359 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233360 ASSERT_TRUE(response);
3361 ASSERT_TRUE(response->headers);
3362 EXPECT_TRUE(response->headers->IsKeepAlive());
3363 EXPECT_EQ(407, response->headers->response_code());
3364 EXPECT_EQ(10, response->headers->GetContentLength());
3365 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3366 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3367
3368 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3369 // out of scope.
3370 session->CloseAllConnections();
3371 }
3372}
3373
3374// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3375// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3376// the case the server sends extra data on the original socket, so it can't be
3377// reused.
bncd16676a2016-07-20 16:23:013378TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273379 HttpRequestInfo request;
3380 request.method = "GET";
bncce36dca22015-04-21 22:11:233381 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273382 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293383 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273384
[email protected]2d2697f92009-02-18 21:00:323385 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233386 session_deps_.proxy_service =
3387 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513388 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073389 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323391
[email protected]2d2697f92009-02-18 21:00:323392 // Since we have proxy, should try to establish tunnel.
3393 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233394 MockWrite(ASYNC, 0,
3395 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173396 "Host: www.example.org:443\r\n"
3397 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233398 };
[email protected]2d2697f92009-02-18 21:00:323399
mmenked39192ee2015-12-09 00:57:233400 // The proxy responds to the connect with a 407, using a persistent, but sends
3401 // extra data, so the socket cannot be reused.
3402 MockRead data_reads1[] = {
3403 // No credentials.
3404 MockRead(ASYNC, 1,
3405 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3406 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3407 "Content-Length: 10\r\n\r\n"),
3408 MockRead(SYNCHRONOUS, 2, "0123456789"),
3409 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3410 };
3411
3412 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233413 // After calling trans->RestartWithAuth(), this is the request we should
3414 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233415 MockWrite(ASYNC, 0,
3416 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173417 "Host: www.example.org:443\r\n"
3418 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233419 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3420
3421 MockWrite(ASYNC, 2,
3422 "GET / HTTP/1.1\r\n"
3423 "Host: www.example.org\r\n"
3424 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323425 };
3426
mmenked39192ee2015-12-09 00:57:233427 MockRead data_reads2[] = {
3428 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323429
mmenked39192ee2015-12-09 00:57:233430 MockRead(ASYNC, 3,
3431 "HTTP/1.1 200 OK\r\n"
3432 "Content-Type: text/html; charset=iso-8859-1\r\n"
3433 "Content-Length: 5\r\n\r\n"),
3434 // No response body because the test stops reading here.
3435 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323436 };
3437
mmenked39192ee2015-12-09 00:57:233438 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3439 arraysize(data_writes1));
3440 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073441 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233442 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3443 arraysize(data_writes2));
3444 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3445 SSLSocketDataProvider ssl(ASYNC, OK);
3446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323447
[email protected]49639fa2011-12-20 23:22:413448 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323449
bnc87dcefc2017-05-25 12:47:583450 auto trans =
3451 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323452
mmenked39192ee2015-12-09 00:57:233453 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013454 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233455
mmenke43758e62015-05-04 21:09:463456 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403457 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393458 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003459 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3460 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393461 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403462 entries, pos,
mikecirone8b85c432016-09-08 19:11:003463 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3464 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323465
[email protected]1c773ea12009-04-28 19:58:423466 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243467 ASSERT_TRUE(response);
3468 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323469 EXPECT_TRUE(response->headers->IsKeepAlive());
3470 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423471 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043472 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323473
mmenked39192ee2015-12-09 00:57:233474 LoadTimingInfo load_timing_info;
3475 // CONNECT requests and responses are handled at the connect job level, so
3476 // the transaction does not yet have a connection.
3477 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3478
[email protected]49639fa2011-12-20 23:22:413479 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323480
mmenked39192ee2015-12-09 00:57:233481 rv =
3482 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013483 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323484
[email protected]2d2697f92009-02-18 21:00:323485 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233486 EXPECT_EQ(200, response->headers->response_code());
3487 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423488 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133489
mmenked39192ee2015-12-09 00:57:233490 // The password prompt info should not be set.
3491 EXPECT_FALSE(response->auth_challenge);
3492
3493 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3494 TestLoadTimingNotReusedWithPac(load_timing_info,
3495 CONNECT_TIMING_HAS_SSL_TIMES);
3496
3497 trans.reset();
[email protected]102e27c2011-02-23 01:01:313498 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323499}
3500
mmenkee71e15332015-10-07 16:39:543501// Test the case a proxy closes a socket while the challenge body is being
3502// drained.
bncd16676a2016-07-20 16:23:013503TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543504 HttpRequestInfo request;
3505 request.method = "GET";
3506 request.url = GURL("https://www.example.org/");
3507 // Ensure that proxy authentication is attempted even
3508 // when the no authentication data flag is set.
3509 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3510
3511 // Configure against proxy server "myproxy:70".
3512 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093513 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543514
bnc691fda62016-08-12 00:43:163515 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543516
3517 // Since we have proxy, should try to establish tunnel.
3518 MockWrite data_writes1[] = {
3519 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173520 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543521 "Proxy-Connection: keep-alive\r\n\r\n"),
3522 };
3523
3524 // The proxy responds to the connect with a 407, using a persistent
3525 // connection.
3526 MockRead data_reads1[] = {
3527 // No credentials.
3528 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3529 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3530 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3531 // Server hands up in the middle of the body.
3532 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3533 };
3534
3535 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163536 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543537 // be issuing -- the final header line contains the credentials.
3538 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173539 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543540 "Proxy-Connection: keep-alive\r\n"
3541 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3542
3543 MockWrite("GET / HTTP/1.1\r\n"
3544 "Host: www.example.org\r\n"
3545 "Connection: keep-alive\r\n\r\n"),
3546 };
3547
3548 MockRead data_reads2[] = {
3549 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3550
3551 MockRead("HTTP/1.1 200 OK\r\n"),
3552 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3553 MockRead("Content-Length: 5\r\n\r\n"),
3554 MockRead(SYNCHRONOUS, "hello"),
3555 };
3556
3557 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3558 data_writes1, arraysize(data_writes1));
3559 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3560 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3561 data_writes2, arraysize(data_writes2));
3562 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3563 SSLSocketDataProvider ssl(ASYNC, OK);
3564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3565
3566 TestCompletionCallback callback;
3567
tfarina42834112016-09-22 13:38:203568 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013569 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543570
bnc691fda62016-08-12 00:43:163571 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543572 ASSERT_TRUE(response);
3573 ASSERT_TRUE(response->headers);
3574 EXPECT_TRUE(response->headers->IsKeepAlive());
3575 EXPECT_EQ(407, response->headers->response_code());
3576 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3577
bnc691fda62016-08-12 00:43:163578 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013579 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543580
bnc691fda62016-08-12 00:43:163581 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543582 ASSERT_TRUE(response);
3583 ASSERT_TRUE(response->headers);
3584 EXPECT_TRUE(response->headers->IsKeepAlive());
3585 EXPECT_EQ(200, response->headers->response_code());
3586 std::string body;
bnc691fda62016-08-12 00:43:163587 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543588 EXPECT_EQ("hello", body);
3589}
3590
[email protected]a8e9b162009-03-12 00:06:443591// Test that we don't read the response body when we fail to establish a tunnel,
3592// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013593TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273594 HttpRequestInfo request;
3595 request.method = "GET";
bncce36dca22015-04-21 22:11:233596 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273597
[email protected]a8e9b162009-03-12 00:06:443598 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033599 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443600
danakj1fd259a02016-04-16 03:17:093601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443602
bnc691fda62016-08-12 00:43:163603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443604
[email protected]a8e9b162009-03-12 00:06:443605 // Since we have proxy, should try to establish tunnel.
3606 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173607 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3608 "Host: www.example.org:443\r\n"
3609 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443610 };
3611
3612 // The proxy responds to the connect with a 407.
3613 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243614 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3615 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3616 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233617 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243618 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443619 };
3620
[email protected]31a2bfe2010-02-09 08:03:393621 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3622 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443624
[email protected]49639fa2011-12-20 23:22:413625 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443626
tfarina42834112016-09-22 13:38:203627 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443629
3630 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013631 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443632
bnc691fda62016-08-12 00:43:163633 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243634 ASSERT_TRUE(response);
3635 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443636 EXPECT_TRUE(response->headers->IsKeepAlive());
3637 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423638 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443639
3640 std::string response_data;
bnc691fda62016-08-12 00:43:163641 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013642 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183643
3644 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313645 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443646}
3647
ttuttle7933c112015-01-06 00:55:243648// Test that we don't pass extraneous headers from the proxy's response to the
3649// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013650TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243651 HttpRequestInfo request;
3652 request.method = "GET";
bncce36dca22015-04-21 22:11:233653 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243654
3655 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033656 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243657
danakj1fd259a02016-04-16 03:17:093658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243659
bnc691fda62016-08-12 00:43:163660 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243661
3662 // Since we have proxy, should try to establish tunnel.
3663 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173664 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3665 "Host: www.example.org:443\r\n"
3666 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243667 };
3668
3669 // The proxy responds to the connect with a 407.
3670 MockRead data_reads[] = {
3671 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3672 MockRead("X-Foo: bar\r\n"),
3673 MockRead("Set-Cookie: foo=bar\r\n"),
3674 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3675 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233676 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243677 };
3678
3679 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3680 arraysize(data_writes));
3681 session_deps_.socket_factory->AddSocketDataProvider(&data);
3682
3683 TestCompletionCallback callback;
3684
tfarina42834112016-09-22 13:38:203685 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243687
3688 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013689 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243690
bnc691fda62016-08-12 00:43:163691 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243692 ASSERT_TRUE(response);
3693 ASSERT_TRUE(response->headers);
3694 EXPECT_TRUE(response->headers->IsKeepAlive());
3695 EXPECT_EQ(407, response->headers->response_code());
3696 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3697 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3698 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3699
3700 std::string response_data;
bnc691fda62016-08-12 00:43:163701 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013702 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243703
3704 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3705 session->CloseAllConnections();
3706}
3707
[email protected]8fdbcd22010-05-05 02:54:523708// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3709// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013710TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523711 HttpRequestInfo request;
3712 request.method = "GET";
bncce36dca22015-04-21 22:11:233713 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523714
[email protected]cb9bf6ca2011-01-28 13:15:273715 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273718
[email protected]8fdbcd22010-05-05 02:54:523719 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233720 MockWrite(
3721 "GET / HTTP/1.1\r\n"
3722 "Host: www.example.org\r\n"
3723 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523724 };
3725
3726 MockRead data_reads1[] = {
3727 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3728 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3729 // Large content-length -- won't matter, as connection will be reset.
3730 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063731 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523732 };
3733
3734 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3735 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523737
[email protected]49639fa2011-12-20 23:22:413738 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523739
tfarina42834112016-09-22 13:38:203740 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523742
3743 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013744 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523745}
3746
[email protected]7a67a8152010-11-05 18:31:103747// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3748// through a non-authenticating proxy. The request should fail with
3749// ERR_UNEXPECTED_PROXY_AUTH.
3750// Note that it is impossible to detect if an HTTP server returns a 407 through
3751// a non-authenticating proxy - there is nothing to indicate whether the
3752// response came from the proxy or the server, so it is treated as if the proxy
3753// issued the challenge.
bncd16676a2016-07-20 16:23:013754TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273755 HttpRequestInfo request;
3756 request.method = "GET";
bncce36dca22015-04-21 22:11:233757 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273758
rdsmith82957ad2015-09-16 19:42:033759 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513760 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073761 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103763
[email protected]7a67a8152010-11-05 18:31:103764 // Since we have proxy, should try to establish tunnel.
3765 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173766 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3767 "Host: www.example.org:443\r\n"
3768 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103769
rsleevidb16bb02015-11-12 23:47:173770 MockWrite("GET / HTTP/1.1\r\n"
3771 "Host: www.example.org\r\n"
3772 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103773 };
3774
3775 MockRead data_reads1[] = {
3776 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3777
3778 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3779 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3780 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063781 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103782 };
3783
3784 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3785 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073786 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063787 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073788 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103789
[email protected]49639fa2011-12-20 23:22:413790 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103791
bnc691fda62016-08-12 00:43:163792 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103793
bnc691fda62016-08-12 00:43:163794 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103796
3797 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013798 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463799 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403800 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103801 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003802 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3803 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103804 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403805 entries, pos,
mikecirone8b85c432016-09-08 19:11:003806 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3807 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103808}
[email protected]2df19bb2010-08-25 20:13:463809
mmenke2a1781d2015-10-07 19:25:333810// Test a proxy auth scheme that allows default credentials and a proxy server
3811// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013812TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333813 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3814 HttpRequestInfo request;
3815 request.method = "GET";
3816 request.url = GURL("https://www.example.org/");
3817
3818 // Configure against proxy server "myproxy:70".
3819 session_deps_.proxy_service =
3820 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3821
bnc87dcefc2017-05-25 12:47:583822 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333823 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583824 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333825 mock_handler->set_allows_default_credentials(true);
3826 auth_handler_factory->AddMockHandler(mock_handler.release(),
3827 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483828 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333829
3830 // Add NetLog just so can verify load timing information gets a NetLog ID.
3831 NetLog net_log;
3832 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093833 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333834
3835 // Since we have proxy, should try to establish tunnel.
3836 MockWrite data_writes1[] = {
3837 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173838 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333839 "Proxy-Connection: keep-alive\r\n\r\n"),
3840 };
3841
3842 // The proxy responds to the connect with a 407, using a non-persistent
3843 // connection.
3844 MockRead data_reads1[] = {
3845 // No credentials.
3846 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3847 MockRead("Proxy-Authenticate: Mock\r\n"),
3848 MockRead("Proxy-Connection: close\r\n\r\n"),
3849 };
3850
3851 // Since the first connection couldn't be reused, need to establish another
3852 // once given credentials.
3853 MockWrite data_writes2[] = {
3854 // After calling trans->RestartWithAuth(), this is the request we should
3855 // be issuing -- the final header line contains the credentials.
3856 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173857 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333858 "Proxy-Connection: keep-alive\r\n"
3859 "Proxy-Authorization: auth_token\r\n\r\n"),
3860
3861 MockWrite("GET / HTTP/1.1\r\n"
3862 "Host: www.example.org\r\n"
3863 "Connection: keep-alive\r\n\r\n"),
3864 };
3865
3866 MockRead data_reads2[] = {
3867 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3868
3869 MockRead("HTTP/1.1 200 OK\r\n"),
3870 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3871 MockRead("Content-Length: 5\r\n\r\n"),
3872 MockRead(SYNCHRONOUS, "hello"),
3873 };
3874
3875 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3876 data_writes1, arraysize(data_writes1));
3877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3878 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3879 data_writes2, arraysize(data_writes2));
3880 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3881 SSLSocketDataProvider ssl(ASYNC, OK);
3882 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3883
bnc87dcefc2017-05-25 12:47:583884 auto trans =
3885 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333886
3887 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203888 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013889 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333890
3891 const HttpResponseInfo* response = trans->GetResponseInfo();
3892 ASSERT_TRUE(response);
3893 ASSERT_TRUE(response->headers);
3894 EXPECT_FALSE(response->headers->IsKeepAlive());
3895 EXPECT_EQ(407, response->headers->response_code());
3896 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3897 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523898 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333899
3900 LoadTimingInfo load_timing_info;
3901 // CONNECT requests and responses are handled at the connect job level, so
3902 // the transaction does not yet have a connection.
3903 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3904
3905 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013906 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333907 response = trans->GetResponseInfo();
3908 ASSERT_TRUE(response);
3909 ASSERT_TRUE(response->headers);
3910 EXPECT_TRUE(response->headers->IsKeepAlive());
3911 EXPECT_EQ(200, response->headers->response_code());
3912 EXPECT_EQ(5, response->headers->GetContentLength());
3913 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3914
3915 // The password prompt info should not be set.
3916 EXPECT_FALSE(response->auth_challenge);
3917
3918 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3919 TestLoadTimingNotReusedWithPac(load_timing_info,
3920 CONNECT_TIMING_HAS_SSL_TIMES);
3921
3922 trans.reset();
3923 session->CloseAllConnections();
3924}
3925
3926// Test a proxy auth scheme that allows default credentials and a proxy server
3927// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013928TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333929 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3930 HttpRequestInfo request;
3931 request.method = "GET";
3932 request.url = GURL("https://www.example.org/");
3933
3934 // Configure against proxy server "myproxy:70".
3935 session_deps_.proxy_service =
3936 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3937
bnc87dcefc2017-05-25 12:47:583938 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333939 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583940 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333941 mock_handler->set_allows_default_credentials(true);
3942 auth_handler_factory->AddMockHandler(mock_handler.release(),
3943 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483944 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333945
3946 // Add NetLog just so can verify load timing information gets a NetLog ID.
3947 NetLog net_log;
3948 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093949 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333950
3951 // Should try to establish tunnel.
3952 MockWrite data_writes1[] = {
3953 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173954 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333955 "Proxy-Connection: keep-alive\r\n\r\n"),
3956
3957 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173958 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333959 "Proxy-Connection: keep-alive\r\n"
3960 "Proxy-Authorization: auth_token\r\n\r\n"),
3961 };
3962
3963 // The proxy responds to the connect with a 407, using a non-persistent
3964 // connection.
3965 MockRead data_reads1[] = {
3966 // No credentials.
3967 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3968 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3969 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3970 };
3971
3972 // Since the first connection was closed, need to establish another once given
3973 // credentials.
3974 MockWrite data_writes2[] = {
3975 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173976 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333977 "Proxy-Connection: keep-alive\r\n"
3978 "Proxy-Authorization: auth_token\r\n\r\n"),
3979
3980 MockWrite("GET / HTTP/1.1\r\n"
3981 "Host: www.example.org\r\n"
3982 "Connection: keep-alive\r\n\r\n"),
3983 };
3984
3985 MockRead data_reads2[] = {
3986 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3987
3988 MockRead("HTTP/1.1 200 OK\r\n"),
3989 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3990 MockRead("Content-Length: 5\r\n\r\n"),
3991 MockRead(SYNCHRONOUS, "hello"),
3992 };
3993
3994 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3995 data_writes1, arraysize(data_writes1));
3996 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3997 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3998 data_writes2, arraysize(data_writes2));
3999 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4000 SSLSocketDataProvider ssl(ASYNC, OK);
4001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4002
bnc87dcefc2017-05-25 12:47:584003 auto trans =
4004 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334005
4006 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204007 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014008 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334009
4010 const HttpResponseInfo* response = trans->GetResponseInfo();
4011 ASSERT_TRUE(response);
4012 ASSERT_TRUE(response->headers);
4013 EXPECT_TRUE(response->headers->IsKeepAlive());
4014 EXPECT_EQ(407, response->headers->response_code());
4015 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4016 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4017 EXPECT_FALSE(response->auth_challenge);
4018
4019 LoadTimingInfo load_timing_info;
4020 // CONNECT requests and responses are handled at the connect job level, so
4021 // the transaction does not yet have a connection.
4022 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4023
4024 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014025 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334026
4027 response = trans->GetResponseInfo();
4028 ASSERT_TRUE(response);
4029 ASSERT_TRUE(response->headers);
4030 EXPECT_TRUE(response->headers->IsKeepAlive());
4031 EXPECT_EQ(200, response->headers->response_code());
4032 EXPECT_EQ(5, response->headers->GetContentLength());
4033 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4034
4035 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524036 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334037
4038 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4039 TestLoadTimingNotReusedWithPac(load_timing_info,
4040 CONNECT_TIMING_HAS_SSL_TIMES);
4041
4042 trans.reset();
4043 session->CloseAllConnections();
4044}
4045
4046// Test a proxy auth scheme that allows default credentials and a proxy server
4047// that hangs up when credentials are initially sent, and hangs up again when
4048// they are retried.
bncd16676a2016-07-20 16:23:014049TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334050 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4051 HttpRequestInfo request;
4052 request.method = "GET";
4053 request.url = GURL("https://www.example.org/");
4054
4055 // Configure against proxy server "myproxy:70".
4056 session_deps_.proxy_service =
4057 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4058
bnc87dcefc2017-05-25 12:47:584059 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334060 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584061 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334062 mock_handler->set_allows_default_credentials(true);
4063 auth_handler_factory->AddMockHandler(mock_handler.release(),
4064 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484065 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334066
4067 // Add NetLog just so can verify load timing information gets a NetLog ID.
4068 NetLog net_log;
4069 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094070 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334071
4072 // Should try to establish tunnel.
4073 MockWrite data_writes1[] = {
4074 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174075 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334076 "Proxy-Connection: keep-alive\r\n\r\n"),
4077
4078 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174079 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334080 "Proxy-Connection: keep-alive\r\n"
4081 "Proxy-Authorization: auth_token\r\n\r\n"),
4082 };
4083
4084 // The proxy responds to the connect with a 407, and then hangs up after the
4085 // second request is sent.
4086 MockRead data_reads1[] = {
4087 // No credentials.
4088 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4089 MockRead("Content-Length: 0\r\n"),
4090 MockRead("Proxy-Connection: keep-alive\r\n"),
4091 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4092 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4093 };
4094
4095 // HttpNetworkTransaction sees a reused connection that was closed with
4096 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4097 // request.
4098 MockWrite data_writes2[] = {
4099 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174100 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334101 "Proxy-Connection: keep-alive\r\n\r\n"),
4102 };
4103
4104 // The proxy, having had more than enough of us, just hangs up.
4105 MockRead data_reads2[] = {
4106 // No credentials.
4107 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4108 };
4109
4110 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4111 data_writes1, arraysize(data_writes1));
4112 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4113 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4114 data_writes2, arraysize(data_writes2));
4115 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4116
bnc87dcefc2017-05-25 12:47:584117 auto trans =
4118 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334119
4120 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204121 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014122 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334123
4124 const HttpResponseInfo* response = trans->GetResponseInfo();
4125 ASSERT_TRUE(response);
4126 ASSERT_TRUE(response->headers);
4127 EXPECT_TRUE(response->headers->IsKeepAlive());
4128 EXPECT_EQ(407, response->headers->response_code());
4129 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4130 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4131 EXPECT_FALSE(response->auth_challenge);
4132
4133 LoadTimingInfo load_timing_info;
4134 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4135
4136 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014137 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334138
4139 trans.reset();
4140 session->CloseAllConnections();
4141}
4142
4143// Test a proxy auth scheme that allows default credentials and a proxy server
4144// that hangs up when credentials are initially sent, and sends a challenge
4145// again they are retried.
bncd16676a2016-07-20 16:23:014146TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334147 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4148 HttpRequestInfo request;
4149 request.method = "GET";
4150 request.url = GURL("https://www.example.org/");
4151
4152 // Configure against proxy server "myproxy:70".
4153 session_deps_.proxy_service =
4154 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4155
bnc87dcefc2017-05-25 12:47:584156 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334157 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584158 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334159 mock_handler->set_allows_default_credentials(true);
4160 auth_handler_factory->AddMockHandler(mock_handler.release(),
4161 HttpAuth::AUTH_PROXY);
4162 // Add another handler for the second challenge. It supports default
4163 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584164 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334165 mock_handler->set_allows_default_credentials(true);
4166 auth_handler_factory->AddMockHandler(mock_handler.release(),
4167 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484168 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334169
4170 // Add NetLog just so can verify load timing information gets a NetLog ID.
4171 NetLog net_log;
4172 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094173 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334174
4175 // Should try to establish tunnel.
4176 MockWrite data_writes1[] = {
4177 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174178 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334179 "Proxy-Connection: keep-alive\r\n\r\n"),
4180 };
4181
4182 // The proxy responds to the connect with a 407, using a non-persistent
4183 // connection.
4184 MockRead data_reads1[] = {
4185 // No credentials.
4186 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4187 MockRead("Proxy-Authenticate: Mock\r\n"),
4188 MockRead("Proxy-Connection: close\r\n\r\n"),
4189 };
4190
4191 // Since the first connection was closed, need to establish another once given
4192 // credentials.
4193 MockWrite data_writes2[] = {
4194 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174195 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334196 "Proxy-Connection: keep-alive\r\n"
4197 "Proxy-Authorization: auth_token\r\n\r\n"),
4198 };
4199
4200 MockRead data_reads2[] = {
4201 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4202 MockRead("Proxy-Authenticate: Mock\r\n"),
4203 MockRead("Proxy-Connection: close\r\n\r\n"),
4204 };
4205
4206 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4207 data_writes1, arraysize(data_writes1));
4208 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4209 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4210 data_writes2, arraysize(data_writes2));
4211 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4212 SSLSocketDataProvider ssl(ASYNC, OK);
4213 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4214
bnc87dcefc2017-05-25 12:47:584215 auto trans =
4216 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334217
4218 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204219 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014220 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334221
4222 const HttpResponseInfo* response = trans->GetResponseInfo();
4223 ASSERT_TRUE(response);
4224 ASSERT_TRUE(response->headers);
4225 EXPECT_EQ(407, response->headers->response_code());
4226 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4227 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4228 EXPECT_FALSE(response->auth_challenge);
4229
4230 LoadTimingInfo load_timing_info;
4231 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4232
4233 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014234 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334235 response = trans->GetResponseInfo();
4236 ASSERT_TRUE(response);
4237 ASSERT_TRUE(response->headers);
4238 EXPECT_EQ(407, response->headers->response_code());
4239 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4240 EXPECT_TRUE(response->auth_challenge);
4241
4242 trans.reset();
4243 session->CloseAllConnections();
4244}
4245
asankae2257db2016-10-11 22:03:164246// A more nuanced test than GenerateAuthToken test which asserts that
4247// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4248// unnecessarily invalidated, and that if the server co-operates, the
4249// authentication handshake can continue with the same scheme but with a
4250// different identity.
4251TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4252 HttpRequestInfo request;
4253 request.method = "GET";
4254 request.url = GURL("http://www.example.org/");
4255
bnc87dcefc2017-05-25 12:47:584256 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164257 auth_handler_factory->set_do_init_from_challenge(true);
4258
4259 // First handler. Uses default credentials, but barfs at generate auth token.
bnc87dcefc2017-05-25 12:47:584260 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164261 mock_handler->set_allows_default_credentials(true);
4262 mock_handler->set_allows_explicit_credentials(true);
4263 mock_handler->set_connection_based(true);
4264 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4265 auth_handler_factory->AddMockHandler(mock_handler.release(),
4266 HttpAuth::AUTH_SERVER);
4267
4268 // Add another handler for the second challenge. It supports default
4269 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584270 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164271 mock_handler->set_allows_default_credentials(true);
4272 mock_handler->set_allows_explicit_credentials(true);
4273 mock_handler->set_connection_based(true);
4274 auth_handler_factory->AddMockHandler(mock_handler.release(),
4275 HttpAuth::AUTH_SERVER);
4276 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4277
4278 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4279
4280 MockWrite data_writes1[] = {
4281 MockWrite("GET / HTTP/1.1\r\n"
4282 "Host: www.example.org\r\n"
4283 "Connection: keep-alive\r\n\r\n"),
4284 };
4285
4286 MockRead data_reads1[] = {
4287 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4288 "WWW-Authenticate: Mock\r\n"
4289 "Connection: keep-alive\r\n\r\n"),
4290 };
4291
4292 // Identical to data_writes1[]. The AuthHandler encounters a
4293 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4294 // transaction procceds without an authorization header.
4295 MockWrite data_writes2[] = {
4296 MockWrite("GET / HTTP/1.1\r\n"
4297 "Host: www.example.org\r\n"
4298 "Connection: keep-alive\r\n\r\n"),
4299 };
4300
4301 MockRead data_reads2[] = {
4302 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4303 "WWW-Authenticate: Mock\r\n"
4304 "Connection: keep-alive\r\n\r\n"),
4305 };
4306
4307 MockWrite data_writes3[] = {
4308 MockWrite("GET / HTTP/1.1\r\n"
4309 "Host: www.example.org\r\n"
4310 "Connection: keep-alive\r\n"
4311 "Authorization: auth_token\r\n\r\n"),
4312 };
4313
4314 MockRead data_reads3[] = {
4315 MockRead("HTTP/1.1 200 OK\r\n"
4316 "Content-Length: 5\r\n"
4317 "Content-Type: text/plain\r\n"
4318 "Connection: keep-alive\r\n\r\n"
4319 "Hello"),
4320 };
4321
4322 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4323 data_writes1, arraysize(data_writes1));
4324 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4325
4326 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4327 data_writes2, arraysize(data_writes2));
4328 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4329
4330 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4331 data_writes3, arraysize(data_writes3));
4332 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4333
bnc87dcefc2017-05-25 12:47:584334 auto trans =
4335 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164336
4337 TestCompletionCallback callback;
4338 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4339 EXPECT_THAT(callback.GetResult(rv), IsOk());
4340
4341 const HttpResponseInfo* response = trans->GetResponseInfo();
4342 ASSERT_TRUE(response);
4343 ASSERT_TRUE(response->headers);
4344 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4345
4346 // The following three tests assert that an authentication challenge was
4347 // received and that the stack is ready to respond to the challenge using
4348 // ambient credentials.
4349 EXPECT_EQ(401, response->headers->response_code());
4350 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4351 EXPECT_FALSE(response->auth_challenge);
4352
4353 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4354 EXPECT_THAT(callback.GetResult(rv), IsOk());
4355 response = trans->GetResponseInfo();
4356 ASSERT_TRUE(response);
4357 ASSERT_TRUE(response->headers);
4358
4359 // The following three tests assert that an authentication challenge was
4360 // received and that the stack needs explicit credentials before it is ready
4361 // to respond to the challenge.
4362 EXPECT_EQ(401, response->headers->response_code());
4363 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4364 EXPECT_TRUE(response->auth_challenge);
4365
4366 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4367 EXPECT_THAT(callback.GetResult(rv), IsOk());
4368 response = trans->GetResponseInfo();
4369 ASSERT_TRUE(response);
4370 ASSERT_TRUE(response->headers);
4371 EXPECT_EQ(200, response->headers->response_code());
4372
4373 trans.reset();
4374 session->CloseAllConnections();
4375}
4376
[email protected]029c83b62013-01-24 05:28:204377// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014378TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204379 HttpRequestInfo request1;
4380 request1.method = "GET";
bncce36dca22015-04-21 22:11:234381 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204382
4383 HttpRequestInfo request2;
4384 request2.method = "GET";
bncce36dca22015-04-21 22:11:234385 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204386
4387 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134388 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514389 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074390 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204392
4393 // Since we have proxy, should try to establish tunnel.
4394 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174395 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4396 "Host: www.example.org:443\r\n"
4397 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204398
rsleevidb16bb02015-11-12 23:47:174399 MockWrite("GET /1 HTTP/1.1\r\n"
4400 "Host: www.example.org\r\n"
4401 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204402
rsleevidb16bb02015-11-12 23:47:174403 MockWrite("GET /2 HTTP/1.1\r\n"
4404 "Host: www.example.org\r\n"
4405 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204406 };
4407
4408 // The proxy responds to the connect with a 407, using a persistent
4409 // connection.
4410 MockRead data_reads1[] = {
4411 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4412
4413 MockRead("HTTP/1.1 200 OK\r\n"),
4414 MockRead("Content-Length: 1\r\n\r\n"),
4415 MockRead(SYNCHRONOUS, "1"),
4416
4417 MockRead("HTTP/1.1 200 OK\r\n"),
4418 MockRead("Content-Length: 2\r\n\r\n"),
4419 MockRead(SYNCHRONOUS, "22"),
4420 };
4421
4422 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4423 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074424 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204425 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204427
4428 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584429 auto trans1 =
4430 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204431
4432 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204434
4435 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014436 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204437
4438 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524439 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474440 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524441 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204442 EXPECT_EQ(1, response1->headers->GetContentLength());
4443
4444 LoadTimingInfo load_timing_info1;
4445 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4446 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4447
4448 trans1.reset();
4449
4450 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584451 auto trans2 =
4452 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204453
4454 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204456
4457 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014458 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204459
4460 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524461 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474462 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524463 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204464 EXPECT_EQ(2, response2->headers->GetContentLength());
4465
4466 LoadTimingInfo load_timing_info2;
4467 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4468 TestLoadTimingReused(load_timing_info2);
4469
4470 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4471
4472 trans2.reset();
4473 session->CloseAllConnections();
4474}
4475
4476// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014477TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204478 HttpRequestInfo request1;
4479 request1.method = "GET";
bncce36dca22015-04-21 22:11:234480 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204481
4482 HttpRequestInfo request2;
4483 request2.method = "GET";
bncce36dca22015-04-21 22:11:234484 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204485
4486 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034487 session_deps_.proxy_service =
4488 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514489 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074490 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094491 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204492
4493 // Since we have proxy, should try to establish tunnel.
4494 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174495 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4496 "Host: www.example.org:443\r\n"
4497 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204498
rsleevidb16bb02015-11-12 23:47:174499 MockWrite("GET /1 HTTP/1.1\r\n"
4500 "Host: www.example.org\r\n"
4501 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204502
rsleevidb16bb02015-11-12 23:47:174503 MockWrite("GET /2 HTTP/1.1\r\n"
4504 "Host: www.example.org\r\n"
4505 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204506 };
4507
4508 // The proxy responds to the connect with a 407, using a persistent
4509 // connection.
4510 MockRead data_reads1[] = {
4511 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4512
4513 MockRead("HTTP/1.1 200 OK\r\n"),
4514 MockRead("Content-Length: 1\r\n\r\n"),
4515 MockRead(SYNCHRONOUS, "1"),
4516
4517 MockRead("HTTP/1.1 200 OK\r\n"),
4518 MockRead("Content-Length: 2\r\n\r\n"),
4519 MockRead(SYNCHRONOUS, "22"),
4520 };
4521
4522 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4523 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074524 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204525 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204527
4528 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584529 auto trans1 =
4530 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204531
4532 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204534
4535 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014536 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204537
4538 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524539 ASSERT_TRUE(response1);
4540 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204541 EXPECT_EQ(1, response1->headers->GetContentLength());
4542
4543 LoadTimingInfo load_timing_info1;
4544 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4545 TestLoadTimingNotReusedWithPac(load_timing_info1,
4546 CONNECT_TIMING_HAS_SSL_TIMES);
4547
4548 trans1.reset();
4549
4550 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584551 auto trans2 =
4552 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204553
4554 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204556
4557 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014558 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204559
4560 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524561 ASSERT_TRUE(response2);
4562 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204563 EXPECT_EQ(2, response2->headers->GetContentLength());
4564
4565 LoadTimingInfo load_timing_info2;
4566 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4567 TestLoadTimingReusedWithPac(load_timing_info2);
4568
4569 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4570
4571 trans2.reset();
4572 session->CloseAllConnections();
4573}
4574
[email protected]2df19bb2010-08-25 20:13:464575// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014576TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274577 HttpRequestInfo request;
4578 request.method = "GET";
bncce36dca22015-04-21 22:11:234579 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274580
[email protected]2df19bb2010-08-25 20:13:464581 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034582 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514583 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074584 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094585 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464586
[email protected]2df19bb2010-08-25 20:13:464587 // Since we have proxy, should use full url
4588 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234589 MockWrite(
4590 "GET http://www.example.org/ HTTP/1.1\r\n"
4591 "Host: www.example.org\r\n"
4592 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464593 };
4594
4595 MockRead data_reads1[] = {
4596 MockRead("HTTP/1.1 200 OK\r\n"),
4597 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4598 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064599 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464600 };
4601
4602 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4603 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074604 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064605 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464607
[email protected]49639fa2011-12-20 23:22:414608 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464609
bnc691fda62016-08-12 00:43:164610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504611
bnc691fda62016-08-12 00:43:164612 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464614
4615 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014616 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464617
[email protected]58e32bb2013-01-21 18:23:254618 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164619 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254620 TestLoadTimingNotReused(load_timing_info,
4621 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4622
bnc691fda62016-08-12 00:43:164623 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524624 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464625
tbansal2ecbbc72016-10-06 17:15:474626 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464627 EXPECT_TRUE(response->headers->IsKeepAlive());
4628 EXPECT_EQ(200, response->headers->response_code());
4629 EXPECT_EQ(100, response->headers->GetContentLength());
4630 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4631
4632 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524633 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464634}
4635
[email protected]7642b5ae2010-09-01 20:55:174636// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014637TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274638 HttpRequestInfo request;
4639 request.method = "GET";
bncce36dca22015-04-21 22:11:234640 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274641
[email protected]7642b5ae2010-09-01 20:55:174642 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034643 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514644 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074645 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174647
bncce36dca22015-04-21 22:11:234648 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414649 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454650 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414651 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174652
bnc42331402016-07-25 13:36:154653 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414654 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174655 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414656 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174657 };
4658
rch8e6c6c42015-05-01 14:05:134659 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4660 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074661 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174662
[email protected]8ddf8322012-02-23 18:08:064663 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364664 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074665 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174666
[email protected]49639fa2011-12-20 23:22:414667 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174668
bnc691fda62016-08-12 00:43:164669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504670
bnc691fda62016-08-12 00:43:164671 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174673
4674 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014675 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174676
[email protected]58e32bb2013-01-21 18:23:254677 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164678 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254679 TestLoadTimingNotReused(load_timing_info,
4680 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4681
bnc691fda62016-08-12 00:43:164682 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524683 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474684 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524685 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024686 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174687
4688 std::string response_data;
bnc691fda62016-08-12 00:43:164689 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234690 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174691}
4692
[email protected]1c173852014-06-19 12:51:504693// Verifies that a session which races and wins against the owning transaction
4694// (completing prior to host resolution), doesn't fail the transaction.
4695// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014696TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504697 HttpRequestInfo request;
4698 request.method = "GET";
bncce36dca22015-04-21 22:11:234699 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504700
4701 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034702 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514703 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504704 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504706
bncce36dca22015-04-21 22:11:234707 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414708 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454709 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414710 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504711
bnc42331402016-07-25 13:36:154712 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414713 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504714 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414715 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504716 };
4717
rch8e6c6c42015-05-01 14:05:134718 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4719 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504720 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4721
4722 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364723 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4725
4726 TestCompletionCallback callback1;
4727
bnc691fda62016-08-12 00:43:164728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504729
4730 // Stall the hostname resolution begun by the transaction.
4731 session_deps_.host_resolver->set_synchronous_mode(false);
4732 session_deps_.host_resolver->set_ondemand_mode(true);
4733
bnc691fda62016-08-12 00:43:164734 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504736
4737 // Race a session to the proxy, which completes first.
4738 session_deps_.host_resolver->set_ondemand_mode(false);
4739 SpdySessionKey key(
4740 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4741 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424742 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504743
4744 // Unstall the resolution begun by the transaction.
4745 session_deps_.host_resolver->set_ondemand_mode(true);
4746 session_deps_.host_resolver->ResolveAllPending();
4747
4748 EXPECT_FALSE(callback1.have_result());
4749 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014750 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504751
bnc691fda62016-08-12 00:43:164752 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524753 ASSERT_TRUE(response);
4754 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024755 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504756
4757 std::string response_data;
bnc691fda62016-08-12 00:43:164758 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504759 EXPECT_EQ(kUploadData, response_data);
4760}
4761
[email protected]dc7bd1c52010-11-12 00:01:134762// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014763TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274764 HttpRequestInfo request;
4765 request.method = "GET";
bncce36dca22015-04-21 22:11:234766 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274767
[email protected]79cb5c12011-09-12 13:12:044768 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034769 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514770 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074771 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134773
[email protected]dc7bd1c52010-11-12 00:01:134774 // The first request will be a bare GET, the second request will be a
4775 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454776 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414777 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494778 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384779 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134780 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464781 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134782 };
bncdf80d44fd2016-07-15 20:27:414783 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4784 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4785 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134786 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414787 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134788 };
4789
4790 // The first response is a 407 proxy authentication challenge, and the second
4791 // response will be a 200 response since the second request includes a valid
4792 // Authorization header.
4793 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464794 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134795 };
bnc42331402016-07-25 13:36:154796 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234797 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414798 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4799 SpdySerializedFrame body_authentication(
4800 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154801 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414802 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134803 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414804 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464805 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414806 CreateMockRead(resp_data, 4),
4807 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134808 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134809 };
4810
rch8e6c6c42015-05-01 14:05:134811 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4812 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074813 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134814
[email protected]8ddf8322012-02-23 18:08:064815 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364816 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074817 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134818
[email protected]49639fa2011-12-20 23:22:414819 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134820
bnc691fda62016-08-12 00:43:164821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134822
bnc691fda62016-08-12 00:43:164823 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134825
4826 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014827 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134828
bnc691fda62016-08-12 00:43:164829 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134830
wezca1070932016-05-26 20:30:524831 ASSERT_TRUE(response);
4832 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134833 EXPECT_EQ(407, response->headers->response_code());
4834 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434835 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134836
[email protected]49639fa2011-12-20 23:22:414837 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134838
bnc691fda62016-08-12 00:43:164839 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134841
4842 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014843 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134844
bnc691fda62016-08-12 00:43:164845 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134846
wezca1070932016-05-26 20:30:524847 ASSERT_TRUE(response_restart);
4848 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134849 EXPECT_EQ(200, response_restart->headers->response_code());
4850 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524851 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134852}
4853
[email protected]d9da5fe2010-10-13 22:37:164854// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014855TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274856 HttpRequestInfo request;
4857 request.method = "GET";
bncce36dca22015-04-21 22:11:234858 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274859
[email protected]d9da5fe2010-10-13 22:37:164860 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034861 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514862 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074863 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164865
bnc691fda62016-08-12 00:43:164866 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164867
bncce36dca22015-04-21 22:11:234868 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414869 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234870 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4871 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164872
bncce36dca22015-04-21 22:11:234873 const char get[] =
4874 "GET / HTTP/1.1\r\n"
4875 "Host: www.example.org\r\n"
4876 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414877 SpdySerializedFrame wrapped_get(
4878 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154879 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164880 const char resp[] = "HTTP/1.1 200 OK\r\n"
4881 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414882 SpdySerializedFrame wrapped_get_resp(
4883 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4884 SpdySerializedFrame wrapped_body(
4885 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4886 SpdySerializedFrame window_update(
4887 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044888
4889 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414890 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4891 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044892 };
4893
[email protected]d9da5fe2010-10-13 22:37:164894 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414895 CreateMockRead(conn_resp, 1, ASYNC),
4896 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4897 CreateMockRead(wrapped_body, 4, ASYNC),
4898 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134899 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164900 };
4901
rch8e6c6c42015-05-01 14:05:134902 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4903 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074904 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164905
[email protected]8ddf8322012-02-23 18:08:064906 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364907 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074908 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064909 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074910 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164911
[email protected]49639fa2011-12-20 23:22:414912 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164913
bnc691fda62016-08-12 00:43:164914 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164916
4917 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014918 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164919
[email protected]58e32bb2013-01-21 18:23:254920 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164921 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254922 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4923
bnc691fda62016-08-12 00:43:164924 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524925 ASSERT_TRUE(response);
4926 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164927 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4928
4929 std::string response_data;
bnc691fda62016-08-12 00:43:164930 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164931 EXPECT_EQ("1234567890", response_data);
4932}
4933
4934// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014935TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4936 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384937
[email protected]cb9bf6ca2011-01-28 13:15:274938 HttpRequestInfo request;
4939 request.method = "GET";
bncce36dca22015-04-21 22:11:234940 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274941
[email protected]d9da5fe2010-10-13 22:37:164942 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034943 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514944 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074945 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164947
bnc691fda62016-08-12 00:43:164948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164949
bncce36dca22015-04-21 22:11:234950 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414951 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234952 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4953 // fetch https://www.example.org/ via SPDY
4954 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414955 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494956 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414957 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154958 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414959 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154960 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414961 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024962 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414963 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4964 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024965 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414966 SpdySerializedFrame window_update_get_resp(
4967 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4968 SpdySerializedFrame window_update_body(
4969 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044970
4971 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414972 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4973 CreateMockWrite(window_update_get_resp, 6),
4974 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044975 };
4976
[email protected]d9da5fe2010-10-13 22:37:164977 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414978 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094979 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414980 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4981 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134982 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164983 };
4984
rch32320842015-05-16 15:57:094985 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4986 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074987 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164988
[email protected]8ddf8322012-02-23 18:08:064989 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364990 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074991 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064992 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364993 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164995
[email protected]49639fa2011-12-20 23:22:414996 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164997
bnc691fda62016-08-12 00:43:164998 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165000
rch32320842015-05-16 15:57:095001 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555002 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095003 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595004 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165005 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015006 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165007
[email protected]58e32bb2013-01-21 18:23:255008 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165009 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255010 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5011
bnc691fda62016-08-12 00:43:165012 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525013 ASSERT_TRUE(response);
5014 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025015 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165016
5017 std::string response_data;
bnc691fda62016-08-12 00:43:165018 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235019 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165020}
5021
5022// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015023TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275024 HttpRequestInfo request;
5025 request.method = "GET";
bncce36dca22015-04-21 22:11:235026 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275027
[email protected]d9da5fe2010-10-13 22:37:165028 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035029 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515030 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075031 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165033
bnc691fda62016-08-12 00:43:165034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165035
bncce36dca22015-04-21 22:11:235036 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415037 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235038 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415039 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085040 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165041
5042 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415043 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165044 };
5045
bnc42331402016-07-25 13:36:155046 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415047 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165048 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415049 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165050 };
5051
rch8e6c6c42015-05-01 14:05:135052 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5053 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075054 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165055
[email protected]8ddf8322012-02-23 18:08:065056 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365057 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065059 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365060 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165062
[email protected]49639fa2011-12-20 23:22:415063 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165064
bnc691fda62016-08-12 00:43:165065 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165067
5068 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015069 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165070
ttuttle960fcbf2016-04-19 13:26:325071 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165072}
5073
[email protected]f6c63db52013-02-02 00:35:225074// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5075// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015076TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225077 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5078 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035079 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515080 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075081 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095082 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505083 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225084
5085 HttpRequestInfo request1;
5086 request1.method = "GET";
bncce36dca22015-04-21 22:11:235087 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225088 request1.load_flags = 0;
5089
5090 HttpRequestInfo request2;
5091 request2.method = "GET";
bncce36dca22015-04-21 22:11:235092 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225093 request2.load_flags = 0;
5094
bncce36dca22015-04-21 22:11:235095 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415096 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235097 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155098 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225099
bncce36dca22015-04-21 22:11:235100 // Fetch https://www.example.org/ via HTTP.
5101 const char get1[] =
5102 "GET / HTTP/1.1\r\n"
5103 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225104 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415105 SpdySerializedFrame wrapped_get1(
5106 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225107 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5108 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415109 SpdySerializedFrame wrapped_get_resp1(
5110 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5111 SpdySerializedFrame wrapped_body1(
5112 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5113 SpdySerializedFrame window_update(
5114 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225115
bncce36dca22015-04-21 22:11:235116 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295117 SpdyHeaderBlock connect2_block;
5118 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405119 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155120 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5121 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395122
bnc42331402016-07-25 13:36:155123 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225124
bncce36dca22015-04-21 22:11:235125 // Fetch https://mail.example.org/ via HTTP.
5126 const char get2[] =
5127 "GET / HTTP/1.1\r\n"
5128 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225129 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415130 SpdySerializedFrame wrapped_get2(
5131 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225132 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5133 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415134 SpdySerializedFrame wrapped_get_resp2(
5135 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5136 SpdySerializedFrame wrapped_body2(
5137 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225138
5139 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415140 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5141 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225142 };
5143
5144 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415145 CreateMockRead(conn_resp1, 1, ASYNC),
5146 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5147 CreateMockRead(wrapped_body1, 4, ASYNC),
5148 CreateMockRead(conn_resp2, 6, ASYNC),
5149 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5150 CreateMockRead(wrapped_body2, 9, ASYNC),
5151 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225152 };
5153
mmenke11eb5152015-06-09 14:50:505154 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5155 arraysize(spdy_writes));
5156 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225157
5158 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365159 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225161 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505162 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225163 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225165
5166 TestCompletionCallback callback;
5167
bnc691fda62016-08-12 00:43:165168 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205169 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015170 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225171
5172 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165173 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225174 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5175
bnc691fda62016-08-12 00:43:165176 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525177 ASSERT_TRUE(response);
5178 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225179 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5180
5181 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295182 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165183 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505184 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225185
bnc691fda62016-08-12 00:43:165186 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205187 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015188 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225189
5190 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165191 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225192 // Even though the SPDY connection is reused, a new tunnelled connection has
5193 // to be created, so the socket's load timing looks like a fresh connection.
5194 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5195
5196 // The requests should have different IDs, since they each are using their own
5197 // separate stream.
5198 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5199
bnc691fda62016-08-12 00:43:165200 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505201 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225202}
5203
5204// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5205// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015206TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225207 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5208 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035209 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515210 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075211 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095212 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505213 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225214
5215 HttpRequestInfo request1;
5216 request1.method = "GET";
bncce36dca22015-04-21 22:11:235217 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225218 request1.load_flags = 0;
5219
5220 HttpRequestInfo request2;
5221 request2.method = "GET";
bncce36dca22015-04-21 22:11:235222 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225223 request2.load_flags = 0;
5224
bncce36dca22015-04-21 22:11:235225 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415226 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235227 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155228 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225229
bncce36dca22015-04-21 22:11:235230 // Fetch https://www.example.org/ via HTTP.
5231 const char get1[] =
5232 "GET / HTTP/1.1\r\n"
5233 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225234 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415235 SpdySerializedFrame wrapped_get1(
5236 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225237 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5238 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415239 SpdySerializedFrame wrapped_get_resp1(
5240 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5241 SpdySerializedFrame wrapped_body1(
5242 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5243 SpdySerializedFrame window_update(
5244 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225245
bncce36dca22015-04-21 22:11:235246 // Fetch https://www.example.org/2 via HTTP.
5247 const char get2[] =
5248 "GET /2 HTTP/1.1\r\n"
5249 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225250 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415251 SpdySerializedFrame wrapped_get2(
5252 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225253 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5254 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415255 SpdySerializedFrame wrapped_get_resp2(
5256 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5257 SpdySerializedFrame wrapped_body2(
5258 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225259
5260 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415261 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5262 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225263 };
5264
5265 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415266 CreateMockRead(conn_resp1, 1, ASYNC),
5267 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465268 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415269 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465270 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415271 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225272 };
5273
mmenke11eb5152015-06-09 14:50:505274 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5275 arraysize(spdy_writes));
5276 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225277
5278 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365279 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505280 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225281 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225283
5284 TestCompletionCallback callback;
5285
bnc87dcefc2017-05-25 12:47:585286 auto trans =
5287 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205288 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225290
5291 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015292 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225293
5294 LoadTimingInfo load_timing_info;
5295 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5296 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5297
5298 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525299 ASSERT_TRUE(response);
5300 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225301 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5302
5303 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295304 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505305 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225306 trans.reset();
5307
bnc87dcefc2017-05-25 12:47:585308 auto trans2 =
5309 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205310 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225312
[email protected]f6c63db52013-02-02 00:35:225313 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015314 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225315
5316 LoadTimingInfo load_timing_info2;
5317 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5318 TestLoadTimingReused(load_timing_info2);
5319
5320 // The requests should have the same ID.
5321 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5322
[email protected]90499482013-06-01 00:39:505323 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225324}
5325
5326// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5327// Proxy to different servers.
bncd16676a2016-07-20 16:23:015328TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225329 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035330 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515331 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075332 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095333 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505334 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225335
5336 HttpRequestInfo request1;
5337 request1.method = "GET";
bncce36dca22015-04-21 22:11:235338 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225339 request1.load_flags = 0;
5340
5341 HttpRequestInfo request2;
5342 request2.method = "GET";
bncce36dca22015-04-21 22:11:235343 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225344 request2.load_flags = 0;
5345
bncce36dca22015-04-21 22:11:235346 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265347 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235348 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415349 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155350 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5351 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415352 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385353 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225354
bncce36dca22015-04-21 22:11:235355 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265356 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235357 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415358 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155359 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5360 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415361 SpdySerializedFrame body2(
5362 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225363
5364 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415365 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225366 };
5367
5368 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415369 CreateMockRead(get_resp1, 1, ASYNC),
5370 CreateMockRead(body1, 2, ASYNC),
5371 CreateMockRead(get_resp2, 4, ASYNC),
5372 CreateMockRead(body2, 5, ASYNC),
5373 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225374 };
5375
mmenke11eb5152015-06-09 14:50:505376 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5377 arraysize(spdy_writes));
5378 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225379
5380 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365381 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225383
5384 TestCompletionCallback callback;
5385
bnc87dcefc2017-05-25 12:47:585386 auto trans =
5387 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205388 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015389 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225390
5391 LoadTimingInfo load_timing_info;
5392 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5393 TestLoadTimingNotReused(load_timing_info,
5394 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5395
5396 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525397 ASSERT_TRUE(response);
5398 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025399 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225400
5401 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295402 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505403 rv = trans->Read(buf.get(), 256, callback.callback());
5404 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225405 // Delete the first request, so the second one can reuse the socket.
5406 trans.reset();
5407
bnc691fda62016-08-12 00:43:165408 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205409 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015410 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225411
5412 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165413 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225414 TestLoadTimingReused(load_timing_info2);
5415
5416 // The requests should have the same ID.
5417 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5418
bnc691fda62016-08-12 00:43:165419 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505420 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225421}
5422
[email protected]2df19bb2010-08-25 20:13:465423// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015424TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465425 HttpRequestInfo request;
5426 request.method = "GET";
bncce36dca22015-04-21 22:11:235427 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465428 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295429 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465430
[email protected]79cb5c12011-09-12 13:12:045431 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035432 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515433 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075434 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275436
[email protected]2df19bb2010-08-25 20:13:465437 // Since we have proxy, should use full url
5438 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165439 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5440 "Host: www.example.org\r\n"
5441 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465442
bnc691fda62016-08-12 00:43:165443 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235444 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165445 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5446 "Host: www.example.org\r\n"
5447 "Proxy-Connection: keep-alive\r\n"
5448 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465449 };
5450
5451 // The proxy responds to the GET with a 407, using a persistent
5452 // connection.
5453 MockRead data_reads1[] = {
5454 // No credentials.
5455 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5456 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5457 MockRead("Proxy-Connection: keep-alive\r\n"),
5458 MockRead("Content-Length: 0\r\n\r\n"),
5459
5460 MockRead("HTTP/1.1 200 OK\r\n"),
5461 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5462 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065463 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465464 };
5465
5466 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5467 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075468 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065469 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075470 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465471
[email protected]49639fa2011-12-20 23:22:415472 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465473
bnc691fda62016-08-12 00:43:165474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505475
bnc691fda62016-08-12 00:43:165476 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465478
5479 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015480 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465481
[email protected]58e32bb2013-01-21 18:23:255482 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165483 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255484 TestLoadTimingNotReused(load_timing_info,
5485 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5486
bnc691fda62016-08-12 00:43:165487 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525488 ASSERT_TRUE(response);
5489 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465490 EXPECT_EQ(407, response->headers->response_code());
5491 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435492 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465493
[email protected]49639fa2011-12-20 23:22:415494 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465495
bnc691fda62016-08-12 00:43:165496 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465498
5499 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015500 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465501
[email protected]58e32bb2013-01-21 18:23:255502 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165503 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255504 // Retrying with HTTP AUTH is considered to be reusing a socket.
5505 TestLoadTimingReused(load_timing_info);
5506
bnc691fda62016-08-12 00:43:165507 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525508 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465509
5510 EXPECT_TRUE(response->headers->IsKeepAlive());
5511 EXPECT_EQ(200, response->headers->response_code());
5512 EXPECT_EQ(100, response->headers->GetContentLength());
5513 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5514
5515 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525516 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465517}
5518
[email protected]23e482282013-06-14 16:08:025519void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085520 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425521 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085522 request.method = "GET";
bncce36dca22015-04-21 22:11:235523 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085524
[email protected]cb9bf6ca2011-01-28 13:15:275525 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035526 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095527 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275528
[email protected]c744cf22009-02-27 07:28:085529 // Since we have proxy, should try to establish tunnel.
5530 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175531 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5532 "Host: www.example.org:443\r\n"
5533 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085534 };
5535
5536 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235537 status, MockRead("Content-Length: 10\r\n\r\n"),
5538 // No response body because the test stops reading here.
5539 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085540 };
5541
[email protected]31a2bfe2010-02-09 08:03:395542 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5543 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075544 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085545
[email protected]49639fa2011-12-20 23:22:415546 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085547
bnc691fda62016-08-12 00:43:165548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505549
tfarina42834112016-09-22 13:38:205550 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015551 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085552
5553 rv = callback.WaitForResult();
5554 EXPECT_EQ(expected_status, rv);
5555}
5556
[email protected]23e482282013-06-14 16:08:025557void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235558 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085559 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425560 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085561}
5562
bncd16676a2016-07-20 16:23:015563TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085564 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5565}
5566
bncd16676a2016-07-20 16:23:015567TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085568 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5569}
5570
bncd16676a2016-07-20 16:23:015571TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085572 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5573}
5574
bncd16676a2016-07-20 16:23:015575TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085576 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5577}
5578
bncd16676a2016-07-20 16:23:015579TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085580 ConnectStatusHelper(
5581 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5582}
5583
bncd16676a2016-07-20 16:23:015584TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085585 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5586}
5587
bncd16676a2016-07-20 16:23:015588TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085589 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5590}
5591
bncd16676a2016-07-20 16:23:015592TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085593 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5594}
5595
bncd16676a2016-07-20 16:23:015596TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085597 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5598}
5599
bncd16676a2016-07-20 16:23:015600TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085601 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5602}
5603
bncd16676a2016-07-20 16:23:015604TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085605 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5606}
5607
bncd16676a2016-07-20 16:23:015608TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085609 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5610}
5611
bncd16676a2016-07-20 16:23:015612TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085613 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5614}
5615
bncd16676a2016-07-20 16:23:015616TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085617 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5618}
5619
bncd16676a2016-07-20 16:23:015620TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085621 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5622}
5623
bncd16676a2016-07-20 16:23:015624TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085625 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5626}
5627
bncd16676a2016-07-20 16:23:015628TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375629 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5630}
5631
bncd16676a2016-07-20 16:23:015632TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085633 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5634}
5635
bncd16676a2016-07-20 16:23:015636TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085637 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5638}
5639
bncd16676a2016-07-20 16:23:015640TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085641 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5642}
5643
bncd16676a2016-07-20 16:23:015644TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085645 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5646}
5647
bncd16676a2016-07-20 16:23:015648TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085649 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5650}
5651
bncd16676a2016-07-20 16:23:015652TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085653 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5654}
5655
bncd16676a2016-07-20 16:23:015656TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085657 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5658}
5659
bncd16676a2016-07-20 16:23:015660TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085661 ConnectStatusHelperWithExpectedStatus(
5662 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545663 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085664}
5665
bncd16676a2016-07-20 16:23:015666TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085667 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5668}
5669
bncd16676a2016-07-20 16:23:015670TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085671 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5672}
5673
bncd16676a2016-07-20 16:23:015674TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085675 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5676}
5677
bncd16676a2016-07-20 16:23:015678TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085679 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5680}
5681
bncd16676a2016-07-20 16:23:015682TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085683 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5684}
5685
bncd16676a2016-07-20 16:23:015686TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085687 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5688}
5689
bncd16676a2016-07-20 16:23:015690TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085691 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5692}
5693
bncd16676a2016-07-20 16:23:015694TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085695 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5696}
5697
bncd16676a2016-07-20 16:23:015698TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085699 ConnectStatusHelper(
5700 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5701}
5702
bncd16676a2016-07-20 16:23:015703TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085704 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5705}
5706
bncd16676a2016-07-20 16:23:015707TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085708 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5709}
5710
bncd16676a2016-07-20 16:23:015711TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085712 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5713}
5714
bncd16676a2016-07-20 16:23:015715TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085716 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5717}
5718
bncd16676a2016-07-20 16:23:015719TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085720 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5721}
5722
bncd16676a2016-07-20 16:23:015723TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085724 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5725}
5726
bncd16676a2016-07-20 16:23:015727TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085728 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5729}
5730
[email protected]038e9a32008-10-08 22:40:165731// Test the flow when both the proxy server AND origin server require
5732// authentication. Again, this uses basic auth for both since that is
5733// the simplest to mock.
bncd16676a2016-07-20 16:23:015734TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275735 HttpRequestInfo request;
5736 request.method = "GET";
bncce36dca22015-04-21 22:11:235737 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275738
[email protected]038e9a32008-10-08 22:40:165739 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035740 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075742
bnc691fda62016-08-12 00:43:165743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165744
[email protected]f9ee6b52008-11-08 06:46:235745 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235746 MockWrite(
5747 "GET http://www.example.org/ HTTP/1.1\r\n"
5748 "Host: www.example.org\r\n"
5749 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235750 };
5751
[email protected]038e9a32008-10-08 22:40:165752 MockRead data_reads1[] = {
5753 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5754 // Give a couple authenticate options (only the middle one is actually
5755 // supported).
[email protected]22927ad2009-09-21 19:56:195756 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165757 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5758 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5759 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5760 // Large content-length -- won't matter, as connection will be reset.
5761 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065762 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165763 };
5764
bnc691fda62016-08-12 00:43:165765 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165766 // request we should be issuing -- the final header line contains the
5767 // proxy's credentials.
5768 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235769 MockWrite(
5770 "GET http://www.example.org/ HTTP/1.1\r\n"
5771 "Host: www.example.org\r\n"
5772 "Proxy-Connection: keep-alive\r\n"
5773 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165774 };
5775
5776 // Now the proxy server lets the request pass through to origin server.
5777 // The origin server responds with a 401.
5778 MockRead data_reads2[] = {
5779 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5780 // Note: We are using the same realm-name as the proxy server. This is
5781 // completely valid, as realms are unique across hosts.
5782 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5783 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5784 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065785 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165786 };
5787
bnc691fda62016-08-12 00:43:165788 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165789 // the credentials for both the proxy and origin server.
5790 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235791 MockWrite(
5792 "GET http://www.example.org/ HTTP/1.1\r\n"
5793 "Host: www.example.org\r\n"
5794 "Proxy-Connection: keep-alive\r\n"
5795 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5796 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165797 };
5798
5799 // Lastly we get the desired content.
5800 MockRead data_reads3[] = {
5801 MockRead("HTTP/1.0 200 OK\r\n"),
5802 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5803 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065804 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165805 };
5806
[email protected]31a2bfe2010-02-09 08:03:395807 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5808 data_writes1, arraysize(data_writes1));
5809 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5810 data_writes2, arraysize(data_writes2));
5811 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5812 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5814 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5815 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165816
[email protected]49639fa2011-12-20 23:22:415817 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165818
tfarina42834112016-09-22 13:38:205819 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165821
5822 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015823 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165824
bnc691fda62016-08-12 00:43:165825 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525826 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045827 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165828
[email protected]49639fa2011-12-20 23:22:415829 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165830
bnc691fda62016-08-12 00:43:165831 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165833
5834 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015835 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165836
bnc691fda62016-08-12 00:43:165837 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525838 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045839 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165840
[email protected]49639fa2011-12-20 23:22:415841 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165842
bnc691fda62016-08-12 00:43:165843 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5844 callback3.callback());
robpercival214763f2016-07-01 23:27:015845 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165846
5847 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015848 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165849
bnc691fda62016-08-12 00:43:165850 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525851 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165852 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165853}
[email protected]4ddaf2502008-10-23 18:26:195854
[email protected]ea9dc9a2009-09-05 00:43:325855// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5856// can't hook into its internals to cause it to generate predictable NTLM
5857// authorization headers.
5858#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295859// The NTLM authentication unit tests were generated by capturing the HTTP
5860// requests and responses using Fiddler 2 and inspecting the generated random
5861// bytes in the debugger.
5862
5863// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015864TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425865 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245866 request.method = "GET";
5867 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545868
5869 // Ensure load is not disrupted by flags which suppress behaviour specific
5870 // to other auth schemes.
5871 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245872
[email protected]cb9bf6ca2011-01-28 13:15:275873 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5874 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275876
[email protected]3f918782009-02-28 01:29:245877 MockWrite data_writes1[] = {
5878 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5879 "Host: 172.22.68.17\r\n"
5880 "Connection: keep-alive\r\n\r\n"),
5881 };
5882
5883 MockRead data_reads1[] = {
5884 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045885 // Negotiate and NTLM are often requested together. However, we only want
5886 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5887 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245888 MockRead("WWW-Authenticate: NTLM\r\n"),
5889 MockRead("Connection: close\r\n"),
5890 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365891 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245892 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065893 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245894 };
5895
5896 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165897 // After restarting with a null identity, this is the
5898 // request we should be issuing -- the final header line contains a Type
5899 // 1 message.
5900 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5901 "Host: 172.22.68.17\r\n"
5902 "Connection: keep-alive\r\n"
5903 "Authorization: NTLM "
5904 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245905
bnc691fda62016-08-12 00:43:165906 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5907 // (the credentials for the origin server). The second request continues
5908 // on the same connection.
5909 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5910 "Host: 172.22.68.17\r\n"
5911 "Connection: keep-alive\r\n"
5912 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5913 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5914 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5915 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5916 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245917 };
5918
5919 MockRead data_reads2[] = {
5920 // The origin server responds with a Type 2 message.
5921 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5922 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295923 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245924 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5925 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5926 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5927 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5928 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5929 "BtAAAAAAA=\r\n"),
5930 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365931 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245932 MockRead("You are not authorized to view this page\r\n"),
5933
5934 // Lastly we get the desired content.
5935 MockRead("HTTP/1.1 200 OK\r\n"),
5936 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5937 MockRead("Content-Length: 13\r\n\r\n"),
5938 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065939 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245940 };
5941
[email protected]31a2bfe2010-02-09 08:03:395942 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5943 data_writes1, arraysize(data_writes1));
5944 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5945 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075946 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5947 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245948
[email protected]49639fa2011-12-20 23:22:415949 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245950
bnc691fda62016-08-12 00:43:165951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505952
tfarina42834112016-09-22 13:38:205953 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245955
5956 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015957 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245958
bnc691fda62016-08-12 00:43:165959 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225960
bnc691fda62016-08-12 00:43:165961 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525962 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045963 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245964
[email protected]49639fa2011-12-20 23:22:415965 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255966
bnc691fda62016-08-12 00:43:165967 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5968 callback2.callback());
robpercival214763f2016-07-01 23:27:015969 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255970
5971 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015972 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255973
bnc691fda62016-08-12 00:43:165974 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255975
bnc691fda62016-08-12 00:43:165976 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525977 ASSERT_TRUE(response);
5978 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255979
[email protected]49639fa2011-12-20 23:22:415980 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245981
bnc691fda62016-08-12 00:43:165982 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245984
[email protected]0757e7702009-03-27 04:00:225985 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015986 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245987
bnc691fda62016-08-12 00:43:165988 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525989 ASSERT_TRUE(response);
5990 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245991 EXPECT_EQ(13, response->headers->GetContentLength());
5992}
5993
[email protected]385a4672009-03-11 22:21:295994// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015995TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425996 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295997 request.method = "GET";
5998 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:295999
[email protected]cb9bf6ca2011-01-28 13:15:276000 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
6001 MockGetHostName);
danakj1fd259a02016-04-16 03:17:096002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276003
[email protected]385a4672009-03-11 22:21:296004 MockWrite data_writes1[] = {
6005 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6006 "Host: 172.22.68.17\r\n"
6007 "Connection: keep-alive\r\n\r\n"),
6008 };
6009
6010 MockRead data_reads1[] = {
6011 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046012 // Negotiate and NTLM are often requested together. However, we only want
6013 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6014 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296015 MockRead("WWW-Authenticate: NTLM\r\n"),
6016 MockRead("Connection: close\r\n"),
6017 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366018 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296019 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066020 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296021 };
6022
6023 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166024 // After restarting with a null identity, this is the
6025 // request we should be issuing -- the final header line contains a Type
6026 // 1 message.
6027 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6028 "Host: 172.22.68.17\r\n"
6029 "Connection: keep-alive\r\n"
6030 "Authorization: NTLM "
6031 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296032
bnc691fda62016-08-12 00:43:166033 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6034 // (the credentials for the origin server). The second request continues
6035 // on the same connection.
6036 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6037 "Host: 172.22.68.17\r\n"
6038 "Connection: keep-alive\r\n"
6039 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6040 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6041 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6042 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6043 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296044 };
6045
6046 MockRead data_reads2[] = {
6047 // The origin server responds with a Type 2 message.
6048 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6049 MockRead("WWW-Authenticate: NTLM "
6050 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6051 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6052 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6053 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6054 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6055 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6056 "BtAAAAAAA=\r\n"),
6057 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366058 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296059 MockRead("You are not authorized to view this page\r\n"),
6060
6061 // Wrong password.
6062 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296063 MockRead("WWW-Authenticate: NTLM\r\n"),
6064 MockRead("Connection: close\r\n"),
6065 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366066 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296067 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066068 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296069 };
6070
6071 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166072 // After restarting with a null identity, this is the
6073 // request we should be issuing -- the final header line contains a Type
6074 // 1 message.
6075 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6076 "Host: 172.22.68.17\r\n"
6077 "Connection: keep-alive\r\n"
6078 "Authorization: NTLM "
6079 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296080
bnc691fda62016-08-12 00:43:166081 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6082 // (the credentials for the origin server). The second request continues
6083 // on the same connection.
6084 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6085 "Host: 172.22.68.17\r\n"
6086 "Connection: keep-alive\r\n"
6087 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6088 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6089 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6090 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6091 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296092 };
6093
6094 MockRead data_reads3[] = {
6095 // The origin server responds with a Type 2 message.
6096 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6097 MockRead("WWW-Authenticate: NTLM "
6098 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6099 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6100 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6101 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6102 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6103 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6104 "BtAAAAAAA=\r\n"),
6105 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366106 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296107 MockRead("You are not authorized to view this page\r\n"),
6108
6109 // Lastly we get the desired content.
6110 MockRead("HTTP/1.1 200 OK\r\n"),
6111 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6112 MockRead("Content-Length: 13\r\n\r\n"),
6113 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066114 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296115 };
6116
[email protected]31a2bfe2010-02-09 08:03:396117 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6118 data_writes1, arraysize(data_writes1));
6119 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6120 data_writes2, arraysize(data_writes2));
6121 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6122 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076123 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6124 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6125 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296126
[email protected]49639fa2011-12-20 23:22:416127 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296128
bnc691fda62016-08-12 00:43:166129 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506130
tfarina42834112016-09-22 13:38:206131 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296133
6134 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016135 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296136
bnc691fda62016-08-12 00:43:166137 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296138
bnc691fda62016-08-12 00:43:166139 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526140 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046141 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296142
[email protected]49639fa2011-12-20 23:22:416143 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296144
[email protected]0757e7702009-03-27 04:00:226145 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166146 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6147 callback2.callback());
robpercival214763f2016-07-01 23:27:016148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296149
[email protected]10af5fe72011-01-31 16:17:256150 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016151 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296152
bnc691fda62016-08-12 00:43:166153 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416154 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166155 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256157 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016158 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166159 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226160
bnc691fda62016-08-12 00:43:166161 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526162 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046163 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226164
[email protected]49639fa2011-12-20 23:22:416165 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226166
6167 // Now enter the right password.
bnc691fda62016-08-12 00:43:166168 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6169 callback4.callback());
robpercival214763f2016-07-01 23:27:016170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256171
6172 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016173 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256174
bnc691fda62016-08-12 00:43:166175 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256176
[email protected]49639fa2011-12-20 23:22:416177 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256178
6179 // One more roundtrip
bnc691fda62016-08-12 00:43:166180 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226182
6183 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016184 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226185
bnc691fda62016-08-12 00:43:166186 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526187 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296188 EXPECT_EQ(13, response->headers->GetContentLength());
6189}
[email protected]ea9dc9a2009-09-05 00:43:326190#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296191
[email protected]4ddaf2502008-10-23 18:26:196192// Test reading a server response which has only headers, and no body.
6193// After some maximum number of bytes is consumed, the transaction should
6194// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016195TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426196 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196197 request.method = "GET";
bncce36dca22015-04-21 22:11:236198 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196199
danakj1fd259a02016-04-16 03:17:096200 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276202
[email protected]b75b7b2f2009-10-06 00:54:536203 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436204 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536205 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196206
6207 MockRead data_reads[] = {
6208 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066209 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196210 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066211 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196212 };
[email protected]31a2bfe2010-02-09 08:03:396213 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076214 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196215
[email protected]49639fa2011-12-20 23:22:416216 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196217
tfarina42834112016-09-22 13:38:206218 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196220
6221 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016222 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196223}
[email protected]f4e426b2008-11-05 00:24:496224
6225// Make sure that we don't try to reuse a TCPClientSocket when failing to
6226// establish tunnel.
6227// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016228TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276229 HttpRequestInfo request;
6230 request.method = "GET";
bncce36dca22015-04-21 22:11:236231 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276232
[email protected]f4e426b2008-11-05 00:24:496233 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036234 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016235
danakj1fd259a02016-04-16 03:17:096236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496237
bnc87dcefc2017-05-25 12:47:586238 auto trans =
6239 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496240
[email protected]f4e426b2008-11-05 00:24:496241 // Since we have proxy, should try to establish tunnel.
6242 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176243 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6244 "Host: www.example.org:443\r\n"
6245 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496246 };
6247
[email protected]77848d12008-11-14 00:00:226248 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496249 // connection. Usually a proxy would return 501 (not implemented),
6250 // or 200 (tunnel established).
6251 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236252 MockRead("HTTP/1.1 404 Not Found\r\n"),
6253 MockRead("Content-Length: 10\r\n\r\n"),
6254 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496255 };
6256
[email protected]31a2bfe2010-02-09 08:03:396257 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6258 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076259 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496260
[email protected]49639fa2011-12-20 23:22:416261 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496262
tfarina42834112016-09-22 13:38:206263 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496265
6266 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016267 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496268
[email protected]b4404c02009-04-10 16:38:526269 // Empty the current queue. This is necessary because idle sockets are
6270 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556271 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526272
[email protected]f4e426b2008-11-05 00:24:496273 // We now check to make sure the TCPClientSocket was not added back to
6274 // the pool.
[email protected]90499482013-06-01 00:39:506275 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496276 trans.reset();
fdoray92e35a72016-06-10 15:54:556277 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496278 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506279 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496280}
[email protected]372d34a2008-11-05 21:30:516281
[email protected]1b157c02009-04-21 01:55:406282// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016283TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426284 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406285 request.method = "GET";
bncce36dca22015-04-21 22:11:236286 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406287
danakj1fd259a02016-04-16 03:17:096288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276289
bnc691fda62016-08-12 00:43:166290 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276291
[email protected]1b157c02009-04-21 01:55:406292 MockRead data_reads[] = {
6293 // A part of the response body is received with the response headers.
6294 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6295 // The rest of the response body is received in two parts.
6296 MockRead("lo"),
6297 MockRead(" world"),
6298 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066299 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406300 };
6301
[email protected]31a2bfe2010-02-09 08:03:396302 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076303 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406304
[email protected]49639fa2011-12-20 23:22:416305 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406306
tfarina42834112016-09-22 13:38:206307 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406309
6310 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016311 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406312
bnc691fda62016-08-12 00:43:166313 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526314 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406315
wezca1070932016-05-26 20:30:526316 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406317 std::string status_line = response->headers->GetStatusLine();
6318 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6319
[email protected]90499482013-06-01 00:39:506320 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406321
6322 std::string response_data;
bnc691fda62016-08-12 00:43:166323 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016324 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406325 EXPECT_EQ("hello world", response_data);
6326
6327 // Empty the current queue. This is necessary because idle sockets are
6328 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556329 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406330
6331 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506332 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406333}
6334
[email protected]76a505b2010-08-25 06:23:006335// Make sure that we recycle a SSL socket after reading all of the response
6336// body.
bncd16676a2016-07-20 16:23:016337TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006338 HttpRequestInfo request;
6339 request.method = "GET";
bncce36dca22015-04-21 22:11:236340 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006341
6342 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236343 MockWrite(
6344 "GET / HTTP/1.1\r\n"
6345 "Host: www.example.org\r\n"
6346 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006347 };
6348
6349 MockRead data_reads[] = {
6350 MockRead("HTTP/1.1 200 OK\r\n"),
6351 MockRead("Content-Length: 11\r\n\r\n"),
6352 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066353 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006354 };
6355
[email protected]8ddf8322012-02-23 18:08:066356 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006358
6359 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6360 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076361 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006362
[email protected]49639fa2011-12-20 23:22:416363 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006364
danakj1fd259a02016-04-16 03:17:096365 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006367
tfarina42834112016-09-22 13:38:206368 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006369
robpercival214763f2016-07-01 23:27:016370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6371 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006372
bnc691fda62016-08-12 00:43:166373 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526374 ASSERT_TRUE(response);
6375 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006376 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6377
[email protected]90499482013-06-01 00:39:506378 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006379
6380 std::string response_data;
bnc691fda62016-08-12 00:43:166381 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016382 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006383 EXPECT_EQ("hello world", response_data);
6384
6385 // Empty the current queue. This is necessary because idle sockets are
6386 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556387 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006388
6389 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506390 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006391}
6392
6393// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6394// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016395TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006396 HttpRequestInfo request;
6397 request.method = "GET";
bncce36dca22015-04-21 22:11:236398 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006399
6400 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236401 MockWrite(
6402 "GET / HTTP/1.1\r\n"
6403 "Host: www.example.org\r\n"
6404 "Connection: keep-alive\r\n\r\n"),
6405 MockWrite(
6406 "GET / HTTP/1.1\r\n"
6407 "Host: www.example.org\r\n"
6408 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006409 };
6410
6411 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426412 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6413 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006414
[email protected]8ddf8322012-02-23 18:08:066415 SSLSocketDataProvider ssl(ASYNC, OK);
6416 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076417 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006419
6420 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6421 data_writes, arraysize(data_writes));
6422 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6423 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076424 session_deps_.socket_factory->AddSocketDataProvider(&data);
6425 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006426
[email protected]49639fa2011-12-20 23:22:416427 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006428
danakj1fd259a02016-04-16 03:17:096429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586430 auto trans =
6431 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006432
tfarina42834112016-09-22 13:38:206433 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006434
robpercival214763f2016-07-01 23:27:016435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6436 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006437
6438 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526439 ASSERT_TRUE(response);
6440 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006441 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6442
[email protected]90499482013-06-01 00:39:506443 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006444
6445 std::string response_data;
6446 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016447 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006448 EXPECT_EQ("hello world", response_data);
6449
6450 // Empty the current queue. This is necessary because idle sockets are
6451 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556452 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006453
6454 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506455 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006456
6457 // Now start the second transaction, which should reuse the previous socket.
6458
bnc87dcefc2017-05-25 12:47:586459 trans =
6460 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006461
tfarina42834112016-09-22 13:38:206462 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006463
robpercival214763f2016-07-01 23:27:016464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6465 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006466
6467 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526468 ASSERT_TRUE(response);
6469 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006470 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6471
[email protected]90499482013-06-01 00:39:506472 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006473
6474 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016475 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006476 EXPECT_EQ("hello world", response_data);
6477
6478 // Empty the current queue. This is necessary because idle sockets are
6479 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556480 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006481
6482 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506483 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006484}
6485
maksim.sisov0adf8592016-07-15 06:25:566486// Grab a socket, use it, and put it back into the pool. Then, make
6487// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016488TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566489 HttpRequestInfo request;
6490 request.method = "GET";
6491 request.url = GURL("http://www.example.org/");
6492 request.load_flags = 0;
6493
6494 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6495
bnc691fda62016-08-12 00:43:166496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566497
6498 MockRead data_reads[] = {
6499 // A part of the response body is received with the response headers.
6500 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6501 // The rest of the response body is received in two parts.
6502 MockRead("lo"), MockRead(" world"),
6503 MockRead("junk"), // Should not be read!!
6504 MockRead(SYNCHRONOUS, OK),
6505 };
6506
6507 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6508 session_deps_.socket_factory->AddSocketDataProvider(&data);
6509
6510 TestCompletionCallback callback;
6511
tfarina42834112016-09-22 13:38:206512 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6514
6515 EXPECT_THAT(callback.GetResult(rv), IsOk());
6516
bnc691fda62016-08-12 00:43:166517 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566518 ASSERT_TRUE(response);
6519 EXPECT_TRUE(response->headers);
6520 std::string status_line = response->headers->GetStatusLine();
6521 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6522
6523 // Make memory critical notification and ensure the transaction still has been
6524 // operating right.
6525 base::MemoryPressureListener::NotifyMemoryPressure(
6526 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6527 base::RunLoop().RunUntilIdle();
6528
6529 // Socket should not be flushed as long as it is not idle.
6530 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6531
6532 std::string response_data;
bnc691fda62016-08-12 00:43:166533 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566534 EXPECT_THAT(rv, IsOk());
6535 EXPECT_EQ("hello world", response_data);
6536
6537 // Empty the current queue. This is necessary because idle sockets are
6538 // added to the connection pool asynchronously with a PostTask.
6539 base::RunLoop().RunUntilIdle();
6540
6541 // We now check to make sure the socket was added back to the pool.
6542 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6543
6544 // Idle sockets should be flushed now.
6545 base::MemoryPressureListener::NotifyMemoryPressure(
6546 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6547 base::RunLoop().RunUntilIdle();
6548
6549 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6550}
6551
6552// Grab an SSL socket, use it, and put it back into the pool. Then, make
6553// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016554TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566555 HttpRequestInfo request;
6556 request.method = "GET";
6557 request.url = GURL("https://www.example.org/");
6558 request.load_flags = 0;
6559
6560 MockWrite data_writes[] = {
6561 MockWrite("GET / HTTP/1.1\r\n"
6562 "Host: www.example.org\r\n"
6563 "Connection: keep-alive\r\n\r\n"),
6564 };
6565
6566 MockRead data_reads[] = {
6567 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6568 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6569
6570 SSLSocketDataProvider ssl(ASYNC, OK);
6571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6572
6573 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6574 arraysize(data_writes));
6575 session_deps_.socket_factory->AddSocketDataProvider(&data);
6576
6577 TestCompletionCallback callback;
6578
6579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566581
6582 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206583 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566584
6585 EXPECT_THAT(callback.GetResult(rv), IsOk());
6586
bnc691fda62016-08-12 00:43:166587 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566588 ASSERT_TRUE(response);
6589 ASSERT_TRUE(response->headers);
6590 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6591
6592 // Make memory critical notification and ensure the transaction still has been
6593 // operating right.
6594 base::MemoryPressureListener::NotifyMemoryPressure(
6595 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6596 base::RunLoop().RunUntilIdle();
6597
6598 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6599
6600 std::string response_data;
bnc691fda62016-08-12 00:43:166601 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566602 EXPECT_THAT(rv, IsOk());
6603 EXPECT_EQ("hello world", response_data);
6604
6605 // Empty the current queue. This is necessary because idle sockets are
6606 // added to the connection pool asynchronously with a PostTask.
6607 base::RunLoop().RunUntilIdle();
6608
6609 // We now check to make sure the socket was added back to the pool.
6610 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6611
6612 // Make memory notification once again and ensure idle socket is closed.
6613 base::MemoryPressureListener::NotifyMemoryPressure(
6614 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6615 base::RunLoop().RunUntilIdle();
6616
6617 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6618}
6619
[email protected]b4404c02009-04-10 16:38:526620// Make sure that we recycle a socket after a zero-length response.
6621// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016622TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426623 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526624 request.method = "GET";
bncce36dca22015-04-21 22:11:236625 request.url = GURL(
6626 "http://www.example.org/csi?v=3&s=web&action=&"
6627 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6628 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6629 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526630
danakj1fd259a02016-04-16 03:17:096631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276632
[email protected]b4404c02009-04-10 16:38:526633 MockRead data_reads[] = {
6634 MockRead("HTTP/1.1 204 No Content\r\n"
6635 "Content-Length: 0\r\n"
6636 "Content-Type: text/html\r\n\r\n"),
6637 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066638 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526639 };
6640
[email protected]31a2bfe2010-02-09 08:03:396641 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076642 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526643
mmenkecc2298e2015-12-07 18:20:186644 // Transaction must be created after the MockReads, so it's destroyed before
6645 // them.
bnc691fda62016-08-12 00:43:166646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186647
[email protected]49639fa2011-12-20 23:22:416648 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526649
tfarina42834112016-09-22 13:38:206650 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526652
6653 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016654 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526655
bnc691fda62016-08-12 00:43:166656 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526657 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526658
wezca1070932016-05-26 20:30:526659 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526660 std::string status_line = response->headers->GetStatusLine();
6661 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6662
[email protected]90499482013-06-01 00:39:506663 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526664
6665 std::string response_data;
bnc691fda62016-08-12 00:43:166666 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016667 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526668 EXPECT_EQ("", response_data);
6669
6670 // Empty the current queue. This is necessary because idle sockets are
6671 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556672 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526673
6674 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506675 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526676}
6677
bncd16676a2016-07-20 16:23:016678TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096679 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226680 element_readers.push_back(
ricea2deef682016-09-09 08:04:076681 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226682 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276683
[email protected]1c773ea12009-04-28 19:58:426684 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516685 // Transaction 1: a GET request that succeeds. The socket is recycled
6686 // after use.
6687 request[0].method = "GET";
6688 request[0].url = GURL("http://www.google.com/");
6689 request[0].load_flags = 0;
6690 // Transaction 2: a POST request. Reuses the socket kept alive from
6691 // transaction 1. The first attempts fails when writing the POST data.
6692 // This causes the transaction to retry with a new socket. The second
6693 // attempt succeeds.
6694 request[1].method = "POST";
6695 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276696 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516697 request[1].load_flags = 0;
6698
danakj1fd259a02016-04-16 03:17:096699 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516700
6701 // The first socket is used for transaction 1 and the first attempt of
6702 // transaction 2.
6703
6704 // The response of transaction 1.
6705 MockRead data_reads1[] = {
6706 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6707 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066708 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516709 };
6710 // The mock write results of transaction 1 and the first attempt of
6711 // transaction 2.
6712 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066713 MockWrite(SYNCHRONOUS, 64), // GET
6714 MockWrite(SYNCHRONOUS, 93), // POST
6715 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516716 };
[email protected]31a2bfe2010-02-09 08:03:396717 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6718 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516719
6720 // The second socket is used for the second attempt of transaction 2.
6721
6722 // The response of transaction 2.
6723 MockRead data_reads2[] = {
6724 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6725 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066726 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516727 };
6728 // The mock write results of the second attempt of transaction 2.
6729 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066730 MockWrite(SYNCHRONOUS, 93), // POST
6731 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516732 };
[email protected]31a2bfe2010-02-09 08:03:396733 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6734 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516735
[email protected]bb88e1d32013-05-03 23:11:076736 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6737 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516738
thestig9d3bb0c2015-01-24 00:49:516739 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516740 "hello world", "welcome"
6741 };
6742
6743 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516745
[email protected]49639fa2011-12-20 23:22:416746 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516747
tfarina42834112016-09-22 13:38:206748 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516750
6751 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016752 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516753
bnc691fda62016-08-12 00:43:166754 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526755 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516756
wezca1070932016-05-26 20:30:526757 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516758 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6759
6760 std::string response_data;
bnc691fda62016-08-12 00:43:166761 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016762 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516763 EXPECT_EQ(kExpectedResponseData[i], response_data);
6764 }
6765}
[email protected]f9ee6b52008-11-08 06:46:236766
6767// Test the request-challenge-retry sequence for basic auth when there is
6768// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166769// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016770TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426771 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236772 request.method = "GET";
bncce36dca22015-04-21 22:11:236773 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416774 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296775
danakj1fd259a02016-04-16 03:17:096776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276778
[email protected]a97cca42009-08-14 01:00:296779 // The password contains an escaped character -- for this test to pass it
6780 // will need to be unescaped by HttpNetworkTransaction.
6781 EXPECT_EQ("b%40r", request.url.password());
6782
[email protected]f9ee6b52008-11-08 06:46:236783 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236784 MockWrite(
6785 "GET / HTTP/1.1\r\n"
6786 "Host: www.example.org\r\n"
6787 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236788 };
6789
6790 MockRead data_reads1[] = {
6791 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6792 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6793 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066794 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236795 };
6796
[email protected]2262e3a2012-05-22 16:08:166797 // After the challenge above, the transaction will be restarted using the
6798 // identity from the url (foo, b@r) to answer the challenge.
6799 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236800 MockWrite(
6801 "GET / HTTP/1.1\r\n"
6802 "Host: www.example.org\r\n"
6803 "Connection: keep-alive\r\n"
6804 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166805 };
6806
6807 MockRead data_reads2[] = {
6808 MockRead("HTTP/1.0 200 OK\r\n"),
6809 MockRead("Content-Length: 100\r\n\r\n"),
6810 MockRead(SYNCHRONOUS, OK),
6811 };
6812
[email protected]31a2bfe2010-02-09 08:03:396813 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6814 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166815 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6816 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076817 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6818 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236819
[email protected]49639fa2011-12-20 23:22:416820 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206821 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236823 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016824 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166825 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166826
6827 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166828 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166830 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016831 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166832 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226833
bnc691fda62016-08-12 00:43:166834 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526835 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166836
6837 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526838 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166839
6840 EXPECT_EQ(100, response->headers->GetContentLength());
6841
6842 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556843 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166844}
6845
6846// Test the request-challenge-retry sequence for basic auth when there is an
6847// incorrect identity in the URL. The identity from the URL should be used only
6848// once.
bncd16676a2016-07-20 16:23:016849TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166850 HttpRequestInfo request;
6851 request.method = "GET";
6852 // Note: the URL has a username:password in it. The password "baz" is
6853 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236854 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166855
6856 request.load_flags = LOAD_NORMAL;
6857
danakj1fd259a02016-04-16 03:17:096858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166860
6861 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236862 MockWrite(
6863 "GET / HTTP/1.1\r\n"
6864 "Host: www.example.org\r\n"
6865 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166866 };
6867
6868 MockRead data_reads1[] = {
6869 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6870 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6871 MockRead("Content-Length: 10\r\n\r\n"),
6872 MockRead(SYNCHRONOUS, ERR_FAILED),
6873 };
6874
6875 // After the challenge above, the transaction will be restarted using the
6876 // identity from the url (foo, baz) to answer the challenge.
6877 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236878 MockWrite(
6879 "GET / HTTP/1.1\r\n"
6880 "Host: www.example.org\r\n"
6881 "Connection: keep-alive\r\n"
6882 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166883 };
6884
6885 MockRead data_reads2[] = {
6886 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6887 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6888 MockRead("Content-Length: 10\r\n\r\n"),
6889 MockRead(SYNCHRONOUS, ERR_FAILED),
6890 };
6891
6892 // After the challenge above, the transaction will be restarted using the
6893 // identity supplied by the user (foo, bar) to answer the challenge.
6894 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236895 MockWrite(
6896 "GET / HTTP/1.1\r\n"
6897 "Host: www.example.org\r\n"
6898 "Connection: keep-alive\r\n"
6899 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166900 };
6901
6902 MockRead data_reads3[] = {
6903 MockRead("HTTP/1.0 200 OK\r\n"),
6904 MockRead("Content-Length: 100\r\n\r\n"),
6905 MockRead(SYNCHRONOUS, OK),
6906 };
6907
6908 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6909 data_writes1, arraysize(data_writes1));
6910 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6911 data_writes2, arraysize(data_writes2));
6912 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6913 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076914 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6915 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6916 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166917
6918 TestCompletionCallback callback1;
6919
tfarina42834112016-09-22 13:38:206920 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166922
6923 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016924 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166925
bnc691fda62016-08-12 00:43:166926 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166927 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166928 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166930 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016931 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166932 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166933
bnc691fda62016-08-12 00:43:166934 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526935 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166936 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6937
6938 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166939 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166941 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016942 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166943 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166944
bnc691fda62016-08-12 00:43:166945 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526946 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166947
6948 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526949 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166950
6951 EXPECT_EQ(100, response->headers->GetContentLength());
6952
[email protected]ea9dc9a2009-09-05 00:43:326953 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556954 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326955}
6956
[email protected]2217aa22013-10-11 03:03:546957
6958// Test the request-challenge-retry sequence for basic auth when there is a
6959// correct identity in the URL, but its use is being suppressed. The identity
6960// from the URL should never be used.
bncd16676a2016-07-20 16:23:016961TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546962 HttpRequestInfo request;
6963 request.method = "GET";
bncce36dca22015-04-21 22:11:236964 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546965 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6966
danakj1fd259a02016-04-16 03:17:096967 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166968 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546969
6970 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236971 MockWrite(
6972 "GET / HTTP/1.1\r\n"
6973 "Host: www.example.org\r\n"
6974 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546975 };
6976
6977 MockRead data_reads1[] = {
6978 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6979 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6980 MockRead("Content-Length: 10\r\n\r\n"),
6981 MockRead(SYNCHRONOUS, ERR_FAILED),
6982 };
6983
6984 // After the challenge above, the transaction will be restarted using the
6985 // identity supplied by the user, not the one in the URL, to answer the
6986 // challenge.
6987 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236988 MockWrite(
6989 "GET / HTTP/1.1\r\n"
6990 "Host: www.example.org\r\n"
6991 "Connection: keep-alive\r\n"
6992 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546993 };
6994
6995 MockRead data_reads3[] = {
6996 MockRead("HTTP/1.0 200 OK\r\n"),
6997 MockRead("Content-Length: 100\r\n\r\n"),
6998 MockRead(SYNCHRONOUS, OK),
6999 };
7000
7001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7002 data_writes1, arraysize(data_writes1));
7003 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7004 data_writes3, arraysize(data_writes3));
7005 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7006 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7007
7008 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207009 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547011 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017012 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167013 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547014
bnc691fda62016-08-12 00:43:167015 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527016 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547017 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7018
7019 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167020 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547022 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017023 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167024 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547025
bnc691fda62016-08-12 00:43:167026 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527027 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547028
7029 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527030 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547031 EXPECT_EQ(100, response->headers->GetContentLength());
7032
7033 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557034 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547035}
7036
[email protected]f9ee6b52008-11-08 06:46:237037// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017038TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237040
7041 // Transaction 1: authenticate (foo, bar) on MyRealm1
7042 {
[email protected]1c773ea12009-04-28 19:58:427043 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237044 request.method = "GET";
bncce36dca22015-04-21 22:11:237045 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237046
bnc691fda62016-08-12 00:43:167047 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277048
[email protected]f9ee6b52008-11-08 06:46:237049 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237050 MockWrite(
7051 "GET /x/y/z HTTP/1.1\r\n"
7052 "Host: www.example.org\r\n"
7053 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237054 };
7055
7056 MockRead data_reads1[] = {
7057 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7058 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7059 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067060 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237061 };
7062
7063 // Resend with authorization (username=foo, password=bar)
7064 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237065 MockWrite(
7066 "GET /x/y/z HTTP/1.1\r\n"
7067 "Host: www.example.org\r\n"
7068 "Connection: keep-alive\r\n"
7069 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237070 };
7071
7072 // Sever accepts the authorization.
7073 MockRead data_reads2[] = {
7074 MockRead("HTTP/1.0 200 OK\r\n"),
7075 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067076 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237077 };
7078
[email protected]31a2bfe2010-02-09 08:03:397079 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7080 data_writes1, arraysize(data_writes1));
7081 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7082 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077083 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7084 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237085
[email protected]49639fa2011-12-20 23:22:417086 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237087
tfarina42834112016-09-22 13:38:207088 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237090
7091 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017092 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237093
bnc691fda62016-08-12 00:43:167094 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527095 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047096 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237097
[email protected]49639fa2011-12-20 23:22:417098 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237099
bnc691fda62016-08-12 00:43:167100 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7101 callback2.callback());
robpercival214763f2016-07-01 23:27:017102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237103
7104 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017105 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237106
bnc691fda62016-08-12 00:43:167107 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527108 ASSERT_TRUE(response);
7109 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237110 EXPECT_EQ(100, response->headers->GetContentLength());
7111 }
7112
7113 // ------------------------------------------------------------------------
7114
7115 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7116 {
[email protected]1c773ea12009-04-28 19:58:427117 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237118 request.method = "GET";
7119 // Note that Transaction 1 was at /x/y/z, so this is in the same
7120 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237121 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237122
bnc691fda62016-08-12 00:43:167123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277124
[email protected]f9ee6b52008-11-08 06:46:237125 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237126 MockWrite(
7127 "GET /x/y/a/b HTTP/1.1\r\n"
7128 "Host: www.example.org\r\n"
7129 "Connection: keep-alive\r\n"
7130 // Send preemptive authorization for MyRealm1
7131 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237132 };
7133
7134 // The server didn't like the preemptive authorization, and
7135 // challenges us for a different realm (MyRealm2).
7136 MockRead data_reads1[] = {
7137 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7138 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7139 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067140 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237141 };
7142
7143 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7144 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237145 MockWrite(
7146 "GET /x/y/a/b HTTP/1.1\r\n"
7147 "Host: www.example.org\r\n"
7148 "Connection: keep-alive\r\n"
7149 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237150 };
7151
7152 // Sever accepts the authorization.
7153 MockRead data_reads2[] = {
7154 MockRead("HTTP/1.0 200 OK\r\n"),
7155 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067156 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237157 };
7158
[email protected]31a2bfe2010-02-09 08:03:397159 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7160 data_writes1, arraysize(data_writes1));
7161 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7162 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077163 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7164 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237165
[email protected]49639fa2011-12-20 23:22:417166 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237167
tfarina42834112016-09-22 13:38:207168 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017169 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237170
7171 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017172 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237173
bnc691fda62016-08-12 00:43:167174 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527175 ASSERT_TRUE(response);
7176 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047177 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437178 EXPECT_EQ("http://www.example.org",
7179 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047180 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197181 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237182
[email protected]49639fa2011-12-20 23:22:417183 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237184
bnc691fda62016-08-12 00:43:167185 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7186 callback2.callback());
robpercival214763f2016-07-01 23:27:017187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237188
7189 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017190 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237191
bnc691fda62016-08-12 00:43:167192 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527193 ASSERT_TRUE(response);
7194 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237195 EXPECT_EQ(100, response->headers->GetContentLength());
7196 }
7197
7198 // ------------------------------------------------------------------------
7199
7200 // Transaction 3: Resend a request in MyRealm's protection space --
7201 // succeed with preemptive authorization.
7202 {
[email protected]1c773ea12009-04-28 19:58:427203 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237204 request.method = "GET";
bncce36dca22015-04-21 22:11:237205 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237206
bnc691fda62016-08-12 00:43:167207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277208
[email protected]f9ee6b52008-11-08 06:46:237209 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237210 MockWrite(
7211 "GET /x/y/z2 HTTP/1.1\r\n"
7212 "Host: www.example.org\r\n"
7213 "Connection: keep-alive\r\n"
7214 // The authorization for MyRealm1 gets sent preemptively
7215 // (since the url is in the same protection space)
7216 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237217 };
7218
7219 // Sever accepts the preemptive authorization
7220 MockRead data_reads1[] = {
7221 MockRead("HTTP/1.0 200 OK\r\n"),
7222 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067223 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237224 };
7225
[email protected]31a2bfe2010-02-09 08:03:397226 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7227 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077228 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237229
[email protected]49639fa2011-12-20 23:22:417230 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237231
tfarina42834112016-09-22 13:38:207232 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237234
7235 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017236 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237237
bnc691fda62016-08-12 00:43:167238 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527239 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237240
wezca1070932016-05-26 20:30:527241 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237242 EXPECT_EQ(100, response->headers->GetContentLength());
7243 }
7244
7245 // ------------------------------------------------------------------------
7246
7247 // Transaction 4: request another URL in MyRealm (however the
7248 // url is not known to belong to the protection space, so no pre-auth).
7249 {
[email protected]1c773ea12009-04-28 19:58:427250 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237251 request.method = "GET";
bncce36dca22015-04-21 22:11:237252 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237253
bnc691fda62016-08-12 00:43:167254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277255
[email protected]f9ee6b52008-11-08 06:46:237256 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237257 MockWrite(
7258 "GET /x/1 HTTP/1.1\r\n"
7259 "Host: www.example.org\r\n"
7260 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237261 };
7262
7263 MockRead data_reads1[] = {
7264 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7265 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7266 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067267 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237268 };
7269
7270 // Resend with authorization from MyRealm's cache.
7271 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237272 MockWrite(
7273 "GET /x/1 HTTP/1.1\r\n"
7274 "Host: www.example.org\r\n"
7275 "Connection: keep-alive\r\n"
7276 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237277 };
7278
7279 // Sever accepts the authorization.
7280 MockRead data_reads2[] = {
7281 MockRead("HTTP/1.0 200 OK\r\n"),
7282 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067283 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237284 };
7285
[email protected]31a2bfe2010-02-09 08:03:397286 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7287 data_writes1, arraysize(data_writes1));
7288 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7289 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077290 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7291 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237292
[email protected]49639fa2011-12-20 23:22:417293 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237294
tfarina42834112016-09-22 13:38:207295 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237297
7298 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017299 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237300
bnc691fda62016-08-12 00:43:167301 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417302 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167303 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227305 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017306 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167307 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227308
bnc691fda62016-08-12 00:43:167309 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527310 ASSERT_TRUE(response);
7311 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237312 EXPECT_EQ(100, response->headers->GetContentLength());
7313 }
7314
7315 // ------------------------------------------------------------------------
7316
7317 // Transaction 5: request a URL in MyRealm, but the server rejects the
7318 // cached identity. Should invalidate and re-prompt.
7319 {
[email protected]1c773ea12009-04-28 19:58:427320 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237321 request.method = "GET";
bncce36dca22015-04-21 22:11:237322 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237323
bnc691fda62016-08-12 00:43:167324 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277325
[email protected]f9ee6b52008-11-08 06:46:237326 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237327 MockWrite(
7328 "GET /p/q/t HTTP/1.1\r\n"
7329 "Host: www.example.org\r\n"
7330 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237331 };
7332
7333 MockRead data_reads1[] = {
7334 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7335 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7336 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067337 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237338 };
7339
7340 // Resend with authorization from cache for MyRealm.
7341 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237342 MockWrite(
7343 "GET /p/q/t HTTP/1.1\r\n"
7344 "Host: www.example.org\r\n"
7345 "Connection: keep-alive\r\n"
7346 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237347 };
7348
7349 // Sever rejects the authorization.
7350 MockRead data_reads2[] = {
7351 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7352 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7353 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067354 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237355 };
7356
7357 // At this point we should prompt for new credentials for MyRealm.
7358 // Restart with username=foo3, password=foo4.
7359 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237360 MockWrite(
7361 "GET /p/q/t HTTP/1.1\r\n"
7362 "Host: www.example.org\r\n"
7363 "Connection: keep-alive\r\n"
7364 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237365 };
7366
7367 // Sever accepts the authorization.
7368 MockRead data_reads3[] = {
7369 MockRead("HTTP/1.0 200 OK\r\n"),
7370 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067371 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237372 };
7373
[email protected]31a2bfe2010-02-09 08:03:397374 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7375 data_writes1, arraysize(data_writes1));
7376 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7377 data_writes2, arraysize(data_writes2));
7378 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7379 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077380 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7381 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7382 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237383
[email protected]49639fa2011-12-20 23:22:417384 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237385
tfarina42834112016-09-22 13:38:207386 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017387 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237388
7389 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017390 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237391
bnc691fda62016-08-12 00:43:167392 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417393 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167394 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017395 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227396 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017397 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167398 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227399
bnc691fda62016-08-12 00:43:167400 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527401 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047402 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237403
[email protected]49639fa2011-12-20 23:22:417404 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237405
bnc691fda62016-08-12 00:43:167406 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7407 callback3.callback());
robpercival214763f2016-07-01 23:27:017408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237409
[email protected]0757e7702009-03-27 04:00:227410 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017411 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237412
bnc691fda62016-08-12 00:43:167413 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527414 ASSERT_TRUE(response);
7415 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237416 EXPECT_EQ(100, response->headers->GetContentLength());
7417 }
7418}
[email protected]89ceba9a2009-03-21 03:46:067419
[email protected]3c32c5f2010-05-18 15:18:127420// Tests that nonce count increments when multiple auth attempts
7421// are started with the same nonce.
bncd16676a2016-07-20 16:23:017422TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447423 HttpAuthHandlerDigest::Factory* digest_factory =
7424 new HttpAuthHandlerDigest::Factory();
7425 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7426 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7427 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077428 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127430
7431 // Transaction 1: authenticate (foo, bar) on MyRealm1
7432 {
[email protected]3c32c5f2010-05-18 15:18:127433 HttpRequestInfo request;
7434 request.method = "GET";
bncce36dca22015-04-21 22:11:237435 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127436
bnc691fda62016-08-12 00:43:167437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277438
[email protected]3c32c5f2010-05-18 15:18:127439 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237440 MockWrite(
7441 "GET /x/y/z HTTP/1.1\r\n"
7442 "Host: www.example.org\r\n"
7443 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127444 };
7445
7446 MockRead data_reads1[] = {
7447 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7448 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7449 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067450 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127451 };
7452
7453 // Resend with authorization (username=foo, password=bar)
7454 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237455 MockWrite(
7456 "GET /x/y/z HTTP/1.1\r\n"
7457 "Host: www.example.org\r\n"
7458 "Connection: keep-alive\r\n"
7459 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7460 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7461 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7462 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127463 };
7464
7465 // Sever accepts the authorization.
7466 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087467 MockRead("HTTP/1.0 200 OK\r\n"),
7468 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127469 };
7470
7471 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7472 data_writes1, arraysize(data_writes1));
7473 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7474 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077475 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7476 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127477
[email protected]49639fa2011-12-20 23:22:417478 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127479
tfarina42834112016-09-22 13:38:207480 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127482
7483 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017484 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127485
bnc691fda62016-08-12 00:43:167486 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527487 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047488 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127489
[email protected]49639fa2011-12-20 23:22:417490 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127491
bnc691fda62016-08-12 00:43:167492 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7493 callback2.callback());
robpercival214763f2016-07-01 23:27:017494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127495
7496 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017497 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127498
bnc691fda62016-08-12 00:43:167499 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527500 ASSERT_TRUE(response);
7501 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127502 }
7503
7504 // ------------------------------------------------------------------------
7505
7506 // Transaction 2: Request another resource in digestive's protection space.
7507 // This will preemptively add an Authorization header which should have an
7508 // "nc" value of 2 (as compared to 1 in the first use.
7509 {
[email protected]3c32c5f2010-05-18 15:18:127510 HttpRequestInfo request;
7511 request.method = "GET";
7512 // Note that Transaction 1 was at /x/y/z, so this is in the same
7513 // protection space as digest.
bncce36dca22015-04-21 22:11:237514 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127515
bnc691fda62016-08-12 00:43:167516 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277517
[email protected]3c32c5f2010-05-18 15:18:127518 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237519 MockWrite(
7520 "GET /x/y/a/b HTTP/1.1\r\n"
7521 "Host: www.example.org\r\n"
7522 "Connection: keep-alive\r\n"
7523 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7524 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7525 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7526 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127527 };
7528
7529 // Sever accepts the authorization.
7530 MockRead data_reads1[] = {
7531 MockRead("HTTP/1.0 200 OK\r\n"),
7532 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067533 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127534 };
7535
7536 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7537 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077538 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127539
[email protected]49639fa2011-12-20 23:22:417540 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127541
tfarina42834112016-09-22 13:38:207542 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127544
7545 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017546 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127547
bnc691fda62016-08-12 00:43:167548 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527549 ASSERT_TRUE(response);
7550 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127551 }
7552}
7553
[email protected]89ceba9a2009-03-21 03:46:067554// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017555TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067556 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067559
7560 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167561 trans.read_buf_ = new IOBuffer(15);
7562 trans.read_buf_len_ = 15;
7563 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067564
7565 // Setup state in response_
bnc691fda62016-08-12 00:43:167566 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577567 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087568 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577569 response->response_time = base::Time::Now();
7570 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067571
7572 { // Setup state for response_.vary_data
7573 HttpRequestInfo request;
7574 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7575 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277576 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437577 request.extra_headers.SetHeader("Foo", "1");
7578 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507579 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067580 }
7581
7582 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167583 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067584
7585 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167586 EXPECT_FALSE(trans.read_buf_);
7587 EXPECT_EQ(0, trans.read_buf_len_);
7588 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527589 EXPECT_FALSE(response->auth_challenge);
7590 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047591 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087592 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577593 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067594}
7595
[email protected]bacff652009-03-31 17:50:337596// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017597TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337598 HttpRequestInfo request;
7599 request.method = "GET";
bncce36dca22015-04-21 22:11:237600 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337601
danakj1fd259a02016-04-16 03:17:097602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277604
[email protected]bacff652009-03-31 17:50:337605 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237606 MockWrite(
7607 "GET / HTTP/1.1\r\n"
7608 "Host: www.example.org\r\n"
7609 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337610 };
7611
7612 MockRead data_reads[] = {
7613 MockRead("HTTP/1.0 200 OK\r\n"),
7614 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7615 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067616 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337617 };
7618
[email protected]5ecc992a42009-11-11 01:41:597619 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397620 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7621 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067622 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7623 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337624
[email protected]bb88e1d32013-05-03 23:11:077625 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7626 session_deps_.socket_factory->AddSocketDataProvider(&data);
7627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337629
[email protected]49639fa2011-12-20 23:22:417630 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337631
tfarina42834112016-09-22 13:38:207632 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337634
7635 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017636 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337637
bnc691fda62016-08-12 00:43:167638 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017639 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337640
7641 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017642 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337643
bnc691fda62016-08-12 00:43:167644 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337645
wezca1070932016-05-26 20:30:527646 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337647 EXPECT_EQ(100, response->headers->GetContentLength());
7648}
7649
7650// Test HTTPS connections to a site with a bad certificate, going through a
7651// proxy
bncd16676a2016-07-20 16:23:017652TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037653 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337654
7655 HttpRequestInfo request;
7656 request.method = "GET";
bncce36dca22015-04-21 22:11:237657 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337658
7659 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177660 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7661 "Host: www.example.org:443\r\n"
7662 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337663 };
7664
7665 MockRead proxy_reads[] = {
7666 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067667 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337668 };
7669
7670 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177671 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7672 "Host: www.example.org:443\r\n"
7673 "Proxy-Connection: keep-alive\r\n\r\n"),
7674 MockWrite("GET / HTTP/1.1\r\n"
7675 "Host: www.example.org\r\n"
7676 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337677 };
7678
7679 MockRead data_reads[] = {
7680 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7681 MockRead("HTTP/1.0 200 OK\r\n"),
7682 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7683 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067684 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337685 };
7686
[email protected]31a2bfe2010-02-09 08:03:397687 StaticSocketDataProvider ssl_bad_certificate(
7688 proxy_reads, arraysize(proxy_reads),
7689 proxy_writes, arraysize(proxy_writes));
7690 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7691 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067692 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7693 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337694
[email protected]bb88e1d32013-05-03 23:11:077695 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7696 session_deps_.socket_factory->AddSocketDataProvider(&data);
7697 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7698 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337699
[email protected]49639fa2011-12-20 23:22:417700 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337701
7702 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077703 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337704
danakj1fd259a02016-04-16 03:17:097705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337707
tfarina42834112016-09-22 13:38:207708 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337710
7711 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017712 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337713
bnc691fda62016-08-12 00:43:167714 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337716
7717 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017718 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337719
bnc691fda62016-08-12 00:43:167720 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337721
wezca1070932016-05-26 20:30:527722 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337723 EXPECT_EQ(100, response->headers->GetContentLength());
7724 }
7725}
7726
[email protected]2df19bb2010-08-25 20:13:467727
7728// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017729TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037730 session_deps_.proxy_service =
7731 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517732 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077733 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467734
7735 HttpRequestInfo request;
7736 request.method = "GET";
bncce36dca22015-04-21 22:11:237737 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467738
7739 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177740 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7741 "Host: www.example.org:443\r\n"
7742 "Proxy-Connection: keep-alive\r\n\r\n"),
7743 MockWrite("GET / HTTP/1.1\r\n"
7744 "Host: www.example.org\r\n"
7745 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467746 };
7747
7748 MockRead data_reads[] = {
7749 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7750 MockRead("HTTP/1.1 200 OK\r\n"),
7751 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7752 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067753 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467754 };
7755
7756 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7757 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067758 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7759 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467760
[email protected]bb88e1d32013-05-03 23:11:077761 session_deps_.socket_factory->AddSocketDataProvider(&data);
7762 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7763 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467764
[email protected]49639fa2011-12-20 23:22:417765 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467766
danakj1fd259a02016-04-16 03:17:097767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467769
tfarina42834112016-09-22 13:38:207770 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467772
7773 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017774 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167775 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467776
wezca1070932016-05-26 20:30:527777 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467778
tbansal2ecbbc72016-10-06 17:15:477779 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467780 EXPECT_TRUE(response->headers->IsKeepAlive());
7781 EXPECT_EQ(200, response->headers->response_code());
7782 EXPECT_EQ(100, response->headers->GetContentLength());
7783 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207784
7785 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167786 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207787 TestLoadTimingNotReusedWithPac(load_timing_info,
7788 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467789}
7790
[email protected]511f6f52010-12-17 03:58:297791// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017792TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037793 session_deps_.proxy_service =
7794 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517795 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077796 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297797
7798 HttpRequestInfo request;
7799 request.method = "GET";
bncce36dca22015-04-21 22:11:237800 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297801
7802 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177803 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7804 "Host: www.example.org:443\r\n"
7805 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297806 };
7807
7808 MockRead data_reads[] = {
7809 MockRead("HTTP/1.1 302 Redirect\r\n"),
7810 MockRead("Location: http://login.example.com/\r\n"),
7811 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067812 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297813 };
7814
7815 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7816 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067817 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297818
[email protected]bb88e1d32013-05-03 23:11:077819 session_deps_.socket_factory->AddSocketDataProvider(&data);
7820 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297821
[email protected]49639fa2011-12-20 23:22:417822 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297823
danakj1fd259a02016-04-16 03:17:097824 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167825 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297826
tfarina42834112016-09-22 13:38:207827 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297829
7830 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017831 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167832 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297833
wezca1070932016-05-26 20:30:527834 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297835
7836 EXPECT_EQ(302, response->headers->response_code());
7837 std::string url;
7838 EXPECT_TRUE(response->headers->IsRedirect(&url));
7839 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207840
7841 // In the case of redirects from proxies, HttpNetworkTransaction returns
7842 // timing for the proxy connection instead of the connection to the host,
7843 // and no send / receive times.
7844 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7845 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167846 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207847
7848 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197849 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207850
7851 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7852 EXPECT_LE(load_timing_info.proxy_resolve_start,
7853 load_timing_info.proxy_resolve_end);
7854 EXPECT_LE(load_timing_info.proxy_resolve_end,
7855 load_timing_info.connect_timing.connect_start);
7856 ExpectConnectTimingHasTimes(
7857 load_timing_info.connect_timing,
7858 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7859
7860 EXPECT_TRUE(load_timing_info.send_start.is_null());
7861 EXPECT_TRUE(load_timing_info.send_end.is_null());
7862 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297863}
7864
7865// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017866TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037867 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297868
7869 HttpRequestInfo request;
7870 request.method = "GET";
bncce36dca22015-04-21 22:11:237871 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297872
bncdf80d44fd2016-07-15 20:27:417873 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237874 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417875 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:087876 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297877 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417878 CreateMockWrite(conn, 0, SYNCHRONOUS),
7879 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297880 };
7881
7882 static const char* const kExtraHeaders[] = {
7883 "location",
7884 "http://login.example.com/",
7885 };
bnc42331402016-07-25 13:36:157886 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237887 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297888 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417889 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297890 };
7891
rch8e6c6c42015-05-01 14:05:137892 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7893 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067894 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367895 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297896
[email protected]bb88e1d32013-05-03 23:11:077897 session_deps_.socket_factory->AddSocketDataProvider(&data);
7898 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297899
[email protected]49639fa2011-12-20 23:22:417900 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297901
danakj1fd259a02016-04-16 03:17:097902 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167903 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297904
tfarina42834112016-09-22 13:38:207905 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297907
7908 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017909 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167910 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297911
wezca1070932016-05-26 20:30:527912 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297913
7914 EXPECT_EQ(302, response->headers->response_code());
7915 std::string url;
7916 EXPECT_TRUE(response->headers->IsRedirect(&url));
7917 EXPECT_EQ("http://login.example.com/", url);
7918}
7919
[email protected]4eddbc732012-08-09 05:40:177920// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017921TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037922 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297923
7924 HttpRequestInfo request;
7925 request.method = "GET";
bncce36dca22015-04-21 22:11:237926 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297927
7928 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177929 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7930 "Host: www.example.org:443\r\n"
7931 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297932 };
7933
7934 MockRead data_reads[] = {
7935 MockRead("HTTP/1.1 404 Not Found\r\n"),
7936 MockRead("Content-Length: 23\r\n\r\n"),
7937 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067938 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297939 };
7940
7941 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7942 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067943 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297944
[email protected]bb88e1d32013-05-03 23:11:077945 session_deps_.socket_factory->AddSocketDataProvider(&data);
7946 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297947
[email protected]49639fa2011-12-20 23:22:417948 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297949
danakj1fd259a02016-04-16 03:17:097950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297952
tfarina42834112016-09-22 13:38:207953 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297955
7956 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017957 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297958
ttuttle960fcbf2016-04-19 13:26:327959 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297960}
7961
[email protected]4eddbc732012-08-09 05:40:177962// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017963TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037964 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297965
7966 HttpRequestInfo request;
7967 request.method = "GET";
bncce36dca22015-04-21 22:11:237968 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297969
bncdf80d44fd2016-07-15 20:27:417970 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237971 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417972 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:087973 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297974 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417975 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297976 };
7977
7978 static const char* const kExtraHeaders[] = {
7979 "location",
7980 "http://login.example.com/",
7981 };
bnc42331402016-07-25 13:36:157982 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237983 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:417984 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557985 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297986 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417987 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137988 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297989 };
7990
rch8e6c6c42015-05-01 14:05:137991 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7992 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067993 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367994 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297995
[email protected]bb88e1d32013-05-03 23:11:077996 session_deps_.socket_factory->AddSocketDataProvider(&data);
7997 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297998
[email protected]49639fa2011-12-20 23:22:417999 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298000
danakj1fd259a02016-04-16 03:17:098001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168002 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298003
tfarina42834112016-09-22 13:38:208004 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298006
8007 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018008 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298009
ttuttle960fcbf2016-04-19 13:26:328010 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298011}
8012
[email protected]0c5fb722012-02-28 11:50:358013// Test the request-challenge-retry sequence for basic auth, through
8014// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018015TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358016 HttpRequestInfo request;
8017 request.method = "GET";
bncce36dca22015-04-21 22:11:238018 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358019 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298020 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358021
8022 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038023 session_deps_.proxy_service =
8024 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518025 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078026 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358028
8029 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418030 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238031 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418032 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088033 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388034 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358035
bnc691fda62016-08-12 00:43:168036 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358037 // be issuing -- the final header line contains the credentials.
8038 const char* const kAuthCredentials[] = {
8039 "proxy-authorization", "Basic Zm9vOmJhcg==",
8040 };
bncdf80d44fd2016-07-15 20:27:418041 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348042 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238043 HostPortPair("www.example.org", 443)));
8044 // fetch https://www.example.org/ via HTTP
8045 const char get[] =
8046 "GET / HTTP/1.1\r\n"
8047 "Host: www.example.org\r\n"
8048 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418049 SpdySerializedFrame wrapped_get(
8050 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358051
8052 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418053 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8054 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358055 };
8056
8057 // The proxy responds to the connect with a 407, using a persistent
8058 // connection.
thestig9d3bb0c2015-01-24 00:49:518059 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358060 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358061 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8062 };
bnc42331402016-07-25 13:36:158063 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418064 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358065
bnc42331402016-07-25 13:36:158066 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358067 const char resp[] = "HTTP/1.1 200 OK\r\n"
8068 "Content-Length: 5\r\n\r\n";
8069
bncdf80d44fd2016-07-15 20:27:418070 SpdySerializedFrame wrapped_get_resp(
8071 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8072 SpdySerializedFrame wrapped_body(
8073 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358074 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418075 CreateMockRead(conn_auth_resp, 1, ASYNC),
8076 CreateMockRead(conn_resp, 4, ASYNC),
8077 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8078 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138079 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358080 };
8081
rch8e6c6c42015-05-01 14:05:138082 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8083 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078084 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358085 // Negotiate SPDY to the proxy
8086 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368087 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078088 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358089 // Vanilla SSL to the server
8090 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078091 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358092
8093 TestCompletionCallback callback1;
8094
bnc87dcefc2017-05-25 12:47:588095 auto trans =
8096 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358097
8098 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358100
8101 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018102 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468103 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358104 log.GetEntries(&entries);
8105 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008106 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8107 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358108 ExpectLogContainsSomewhere(
8109 entries, pos,
mikecirone8b85c432016-09-08 19:11:008110 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8111 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358112
8113 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528114 ASSERT_TRUE(response);
8115 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358116 EXPECT_EQ(407, response->headers->response_code());
8117 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528118 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438119 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358120
8121 TestCompletionCallback callback2;
8122
8123 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8124 callback2.callback());
robpercival214763f2016-07-01 23:27:018125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358126
8127 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018128 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358129
8130 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528131 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358132
8133 EXPECT_TRUE(response->headers->IsKeepAlive());
8134 EXPECT_EQ(200, response->headers->response_code());
8135 EXPECT_EQ(5, response->headers->GetContentLength());
8136 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8137
8138 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528139 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358140
[email protected]029c83b62013-01-24 05:28:208141 LoadTimingInfo load_timing_info;
8142 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8143 TestLoadTimingNotReusedWithPac(load_timing_info,
8144 CONNECT_TIMING_HAS_SSL_TIMES);
8145
[email protected]0c5fb722012-02-28 11:50:358146 trans.reset();
8147 session->CloseAllConnections();
8148}
8149
[email protected]7c6f7ba2012-04-03 04:09:298150// Test that an explicitly trusted SPDY proxy can push a resource from an
8151// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018152TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158153 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588154 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158155 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8156 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298157 HttpRequestInfo request;
8158 HttpRequestInfo push_request;
8159
[email protected]7c6f7ba2012-04-03 04:09:298160 request.method = "GET";
bncce36dca22015-04-21 22:11:238161 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298162 push_request.method = "GET";
8163 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8164
tbansal28e68f82016-02-04 02:56:158165 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038166 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158167 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518168 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078169 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508170
inlinechan894515af2016-12-09 02:40:108171 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508172
danakj1fd259a02016-04-16 03:17:098173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298174
bncdf80d44fd2016-07-15 20:27:418175 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458176 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358177 SpdySerializedFrame stream2_priority(
8178 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298179
8180 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418181 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358182 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298183 };
8184
bncdf80d44fd2016-07-15 20:27:418185 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158186 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298187
bncdf80d44fd2016-07-15 20:27:418188 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298189
bncdf80d44fd2016-07-15 20:27:418190 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558191 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438192 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418193 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8194 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298195
8196 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418197 CreateMockRead(stream1_reply, 1, ASYNC),
8198 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358199 CreateMockRead(stream1_body, 4, ASYNC),
8200 CreateMockRead(stream2_body, 5, ASYNC),
8201 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298202 };
8203
rch8e6c6c42015-05-01 14:05:138204 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8205 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078206 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298207 // Negotiate SPDY to the proxy
8208 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368209 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078210 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298211
bnc87dcefc2017-05-25 12:47:588212 auto trans =
8213 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298214 TestCompletionCallback callback;
8215 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298217
8218 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018219 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298220 const HttpResponseInfo* response = trans->GetResponseInfo();
8221
bnc87dcefc2017-05-25 12:47:588222 auto push_trans =
8223 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508224 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298226
8227 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018228 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298229 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8230
wezca1070932016-05-26 20:30:528231 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298232 EXPECT_TRUE(response->headers->IsKeepAlive());
8233
8234 EXPECT_EQ(200, response->headers->response_code());
8235 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8236
8237 std::string response_data;
8238 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018239 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298240 EXPECT_EQ("hello!", response_data);
8241
[email protected]029c83b62013-01-24 05:28:208242 LoadTimingInfo load_timing_info;
8243 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8244 TestLoadTimingNotReusedWithPac(load_timing_info,
8245 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8246
[email protected]7c6f7ba2012-04-03 04:09:298247 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528248 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298249 EXPECT_EQ(200, push_response->headers->response_code());
8250
8251 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018252 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298253 EXPECT_EQ("pushed", response_data);
8254
[email protected]029c83b62013-01-24 05:28:208255 LoadTimingInfo push_load_timing_info;
8256 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8257 TestLoadTimingReusedWithPac(push_load_timing_info);
8258 // The transactions should share a socket ID, despite being for different
8259 // origins.
8260 EXPECT_EQ(load_timing_info.socket_log_id,
8261 push_load_timing_info.socket_log_id);
8262
[email protected]7c6f7ba2012-04-03 04:09:298263 trans.reset();
8264 push_trans.reset();
8265 session->CloseAllConnections();
8266}
8267
[email protected]8c843192012-04-05 07:15:008268// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018269TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158270 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588271 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158272 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8273 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008274 HttpRequestInfo request;
8275
8276 request.method = "GET";
bncce36dca22015-04-21 22:11:238277 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008278
tbansal28e68f82016-02-04 02:56:158279 session_deps_.proxy_service =
8280 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518281 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078282 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508283
8284 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108285 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508286
danakj1fd259a02016-04-16 03:17:098287 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008288
bncdf80d44fd2016-07-15 20:27:418289 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458290 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008291
bncdf80d44fd2016-07-15 20:27:418292 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088293 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008294
8295 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418296 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008297 };
8298
bncdf80d44fd2016-07-15 20:27:418299 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158300 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008301
bncdf80d44fd2016-07-15 20:27:418302 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008303
bncdf80d44fd2016-07-15 20:27:418304 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558305 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008306
8307 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418308 CreateMockRead(stream1_reply, 1, ASYNC),
8309 CreateMockRead(stream2_syn, 2, ASYNC),
8310 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598311 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008312 };
8313
rch8e6c6c42015-05-01 14:05:138314 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8315 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078316 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008317 // Negotiate SPDY to the proxy
8318 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368319 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078320 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008321
bnc87dcefc2017-05-25 12:47:588322 auto trans =
8323 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008324 TestCompletionCallback callback;
8325 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018326 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008327
8328 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018329 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008330 const HttpResponseInfo* response = trans->GetResponseInfo();
8331
wezca1070932016-05-26 20:30:528332 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008333 EXPECT_TRUE(response->headers->IsKeepAlive());
8334
8335 EXPECT_EQ(200, response->headers->response_code());
8336 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8337
8338 std::string response_data;
8339 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018340 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008341 EXPECT_EQ("hello!", response_data);
8342
8343 trans.reset();
8344 session->CloseAllConnections();
8345}
8346
tbansal8ef1d3e2016-02-03 04:05:428347// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8348// resources.
bncd16676a2016-07-20 16:23:018349TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158350 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588351 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158352 proxy_delegate->set_trusted_spdy_proxy(
8353 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8354
tbansal8ef1d3e2016-02-03 04:05:428355 HttpRequestInfo request;
8356
8357 request.method = "GET";
8358 request.url = GURL("http://www.example.org/");
8359
8360 // Configure against https proxy server "myproxy:70".
8361 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8362 BoundTestNetLog log;
8363 session_deps_.net_log = log.bound().net_log();
8364
8365 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108366 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428367
danakj1fd259a02016-04-16 03:17:098368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428369
bncdf80d44fd2016-07-15 20:27:418370 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458371 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358372 SpdySerializedFrame stream2_priority(
8373 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428374
8375 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418376 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358377 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428378 };
8379
bncdf80d44fd2016-07-15 20:27:418380 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158381 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428382
bncdf80d44fd2016-07-15 20:27:418383 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498384 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8385
bncdf80d44fd2016-07-15 20:27:418386 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428387
bncdf80d44fd2016-07-15 20:27:418388 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158389 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428390
bncdf80d44fd2016-07-15 20:27:418391 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428392
8393 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418394 CreateMockRead(stream1_reply, 1, ASYNC),
8395 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358396 CreateMockRead(stream1_body, 4, ASYNC),
8397 CreateMockRead(stream2_body, 5, ASYNC),
8398 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428399 };
8400
8401 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8402 arraysize(spdy_writes));
8403 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8404 // Negotiate SPDY to the proxy
8405 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368406 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428407 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8408
bnc87dcefc2017-05-25 12:47:588409 auto trans =
8410 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428411 TestCompletionCallback callback;
8412 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428414
8415 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018416 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428417 const HttpResponseInfo* response = trans->GetResponseInfo();
8418
wezca1070932016-05-26 20:30:528419 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428420 EXPECT_TRUE(response->headers->IsKeepAlive());
8421
8422 EXPECT_EQ(200, response->headers->response_code());
8423 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8424
8425 std::string response_data;
8426 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018427 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428428 EXPECT_EQ("hello!", response_data);
8429
8430 trans.reset();
8431 session->CloseAllConnections();
8432}
8433
[email protected]2df19bb2010-08-25 20:13:468434// Test HTTPS connections to a site with a bad certificate, going through an
8435// HTTPS proxy
bncd16676a2016-07-20 16:23:018436TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038437 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468438
8439 HttpRequestInfo request;
8440 request.method = "GET";
bncce36dca22015-04-21 22:11:238441 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468442
8443 // Attempt to fetch the URL from a server with a bad cert
8444 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178445 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8446 "Host: www.example.org:443\r\n"
8447 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468448 };
8449
8450 MockRead bad_cert_reads[] = {
8451 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068452 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468453 };
8454
8455 // Attempt to fetch the URL with a good cert
8456 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178457 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8458 "Host: www.example.org:443\r\n"
8459 "Proxy-Connection: keep-alive\r\n\r\n"),
8460 MockWrite("GET / HTTP/1.1\r\n"
8461 "Host: www.example.org\r\n"
8462 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468463 };
8464
8465 MockRead good_cert_reads[] = {
8466 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8467 MockRead("HTTP/1.0 200 OK\r\n"),
8468 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8469 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068470 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468471 };
8472
8473 StaticSocketDataProvider ssl_bad_certificate(
8474 bad_cert_reads, arraysize(bad_cert_reads),
8475 bad_cert_writes, arraysize(bad_cert_writes));
8476 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8477 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068478 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8479 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468480
8481 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078482 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8483 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8484 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468485
8486 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8488 session_deps_.socket_factory->AddSocketDataProvider(&data);
8489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468490
[email protected]49639fa2011-12-20 23:22:418491 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468492
danakj1fd259a02016-04-16 03:17:098493 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468495
tfarina42834112016-09-22 13:38:208496 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468498
8499 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018500 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468501
bnc691fda62016-08-12 00:43:168502 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018503 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468504
8505 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018506 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468507
bnc691fda62016-08-12 00:43:168508 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468509
wezca1070932016-05-26 20:30:528510 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468511 EXPECT_EQ(100, response->headers->GetContentLength());
8512}
8513
bncd16676a2016-07-20 16:23:018514TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428515 HttpRequestInfo request;
8516 request.method = "GET";
bncce36dca22015-04-21 22:11:238517 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438518 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8519 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428520
danakj1fd259a02016-04-16 03:17:098521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278523
[email protected]1c773ea12009-04-28 19:58:428524 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238525 MockWrite(
8526 "GET / HTTP/1.1\r\n"
8527 "Host: www.example.org\r\n"
8528 "Connection: keep-alive\r\n"
8529 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428530 };
8531
8532 // Lastly, the server responds with the actual content.
8533 MockRead data_reads[] = {
8534 MockRead("HTTP/1.0 200 OK\r\n"),
8535 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8536 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068537 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428538 };
8539
[email protected]31a2bfe2010-02-09 08:03:398540 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8541 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078542 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428543
[email protected]49639fa2011-12-20 23:22:418544 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428545
tfarina42834112016-09-22 13:38:208546 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428548
8549 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018550 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428551}
8552
bncd16676a2016-07-20 16:23:018553TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298554 HttpRequestInfo request;
8555 request.method = "GET";
bncce36dca22015-04-21 22:11:238556 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298557 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8558 "Chromium Ultra Awesome X Edition");
8559
rdsmith82957ad2015-09-16 19:42:038560 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168562 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278563
[email protected]da81f132010-08-18 23:39:298564 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178565 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8566 "Host: www.example.org:443\r\n"
8567 "Proxy-Connection: keep-alive\r\n"
8568 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298569 };
8570 MockRead data_reads[] = {
8571 // Return an error, so the transaction stops here (this test isn't
8572 // interested in the rest).
8573 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8574 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8575 MockRead("Proxy-Connection: close\r\n\r\n"),
8576 };
8577
8578 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8579 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078580 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298581
[email protected]49639fa2011-12-20 23:22:418582 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298583
tfarina42834112016-09-22 13:38:208584 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298586
8587 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018588 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298589}
8590
bncd16676a2016-07-20 16:23:018591TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428592 HttpRequestInfo request;
8593 request.method = "GET";
bncce36dca22015-04-21 22:11:238594 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168595 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8596 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428597
danakj1fd259a02016-04-16 03:17:098598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278600
[email protected]1c773ea12009-04-28 19:58:428601 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238602 MockWrite(
8603 "GET / HTTP/1.1\r\n"
8604 "Host: www.example.org\r\n"
8605 "Connection: keep-alive\r\n"
8606 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428607 };
8608
8609 // Lastly, the server responds with the actual content.
8610 MockRead data_reads[] = {
8611 MockRead("HTTP/1.0 200 OK\r\n"),
8612 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8613 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068614 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428615 };
8616
[email protected]31a2bfe2010-02-09 08:03:398617 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8618 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078619 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428620
[email protected]49639fa2011-12-20 23:22:418621 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428622
tfarina42834112016-09-22 13:38:208623 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428625
8626 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018627 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428628}
8629
bncd16676a2016-07-20 16:23:018630TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428631 HttpRequestInfo request;
8632 request.method = "POST";
bncce36dca22015-04-21 22:11:238633 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428634
danakj1fd259a02016-04-16 03:17:098635 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278637
[email protected]1c773ea12009-04-28 19:58:428638 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238639 MockWrite(
8640 "POST / HTTP/1.1\r\n"
8641 "Host: www.example.org\r\n"
8642 "Connection: keep-alive\r\n"
8643 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428644 };
8645
8646 // Lastly, the server responds with the actual content.
8647 MockRead data_reads[] = {
8648 MockRead("HTTP/1.0 200 OK\r\n"),
8649 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8650 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068651 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428652 };
8653
[email protected]31a2bfe2010-02-09 08:03:398654 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8655 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078656 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428657
[email protected]49639fa2011-12-20 23:22:418658 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428659
tfarina42834112016-09-22 13:38:208660 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428662
8663 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018664 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428665}
8666
bncd16676a2016-07-20 16:23:018667TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428668 HttpRequestInfo request;
8669 request.method = "PUT";
bncce36dca22015-04-21 22:11:238670 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428671
danakj1fd259a02016-04-16 03:17:098672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278674
[email protected]1c773ea12009-04-28 19:58:428675 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238676 MockWrite(
8677 "PUT / HTTP/1.1\r\n"
8678 "Host: www.example.org\r\n"
8679 "Connection: keep-alive\r\n"
8680 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428681 };
8682
8683 // Lastly, the server responds with the actual content.
8684 MockRead data_reads[] = {
8685 MockRead("HTTP/1.0 200 OK\r\n"),
8686 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8687 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068688 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428689 };
8690
[email protected]31a2bfe2010-02-09 08:03:398691 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8692 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078693 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428694
[email protected]49639fa2011-12-20 23:22:418695 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428696
tfarina42834112016-09-22 13:38:208697 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428699
8700 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018701 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428702}
8703
bncd16676a2016-07-20 16:23:018704TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428705 HttpRequestInfo request;
8706 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238707 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428708
danakj1fd259a02016-04-16 03:17:098709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278711
[email protected]1c773ea12009-04-28 19:58:428712 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138713 MockWrite("HEAD / HTTP/1.1\r\n"
8714 "Host: www.example.org\r\n"
8715 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428716 };
8717
8718 // Lastly, the server responds with the actual content.
8719 MockRead data_reads[] = {
8720 MockRead("HTTP/1.0 200 OK\r\n"),
8721 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8722 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068723 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428724 };
8725
[email protected]31a2bfe2010-02-09 08:03:398726 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8727 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078728 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428729
[email protected]49639fa2011-12-20 23:22:418730 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428731
tfarina42834112016-09-22 13:38:208732 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428734
8735 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018736 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428737}
8738
bncd16676a2016-07-20 16:23:018739TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428740 HttpRequestInfo request;
8741 request.method = "GET";
bncce36dca22015-04-21 22:11:238742 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428743 request.load_flags = LOAD_BYPASS_CACHE;
8744
danakj1fd259a02016-04-16 03:17:098745 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278747
[email protected]1c773ea12009-04-28 19:58:428748 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238749 MockWrite(
8750 "GET / HTTP/1.1\r\n"
8751 "Host: www.example.org\r\n"
8752 "Connection: keep-alive\r\n"
8753 "Pragma: no-cache\r\n"
8754 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428755 };
8756
8757 // Lastly, the server responds with the actual content.
8758 MockRead data_reads[] = {
8759 MockRead("HTTP/1.0 200 OK\r\n"),
8760 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8761 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068762 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428763 };
8764
[email protected]31a2bfe2010-02-09 08:03:398765 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8766 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078767 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428768
[email protected]49639fa2011-12-20 23:22:418769 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428770
tfarina42834112016-09-22 13:38:208771 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428773
8774 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018775 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428776}
8777
bncd16676a2016-07-20 16:23:018778TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428779 HttpRequestInfo request;
8780 request.method = "GET";
bncce36dca22015-04-21 22:11:238781 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428782 request.load_flags = LOAD_VALIDATE_CACHE;
8783
danakj1fd259a02016-04-16 03:17:098784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278786
[email protected]1c773ea12009-04-28 19:58:428787 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238788 MockWrite(
8789 "GET / HTTP/1.1\r\n"
8790 "Host: www.example.org\r\n"
8791 "Connection: keep-alive\r\n"
8792 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428793 };
8794
8795 // Lastly, the server responds with the actual content.
8796 MockRead data_reads[] = {
8797 MockRead("HTTP/1.0 200 OK\r\n"),
8798 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8799 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068800 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428801 };
8802
[email protected]31a2bfe2010-02-09 08:03:398803 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8804 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078805 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428806
[email protected]49639fa2011-12-20 23:22:418807 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428808
tfarina42834112016-09-22 13:38:208809 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428811
8812 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018813 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428814}
8815
bncd16676a2016-07-20 16:23:018816TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428817 HttpRequestInfo request;
8818 request.method = "GET";
bncce36dca22015-04-21 22:11:238819 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438820 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428821
danakj1fd259a02016-04-16 03:17:098822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278824
[email protected]1c773ea12009-04-28 19:58:428825 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238826 MockWrite(
8827 "GET / HTTP/1.1\r\n"
8828 "Host: www.example.org\r\n"
8829 "Connection: keep-alive\r\n"
8830 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428831 };
8832
8833 // Lastly, the server responds with the actual content.
8834 MockRead data_reads[] = {
8835 MockRead("HTTP/1.0 200 OK\r\n"),
8836 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8837 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068838 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428839 };
8840
[email protected]31a2bfe2010-02-09 08:03:398841 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8842 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078843 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428844
[email protected]49639fa2011-12-20 23:22:418845 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428846
tfarina42834112016-09-22 13:38:208847 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428849
8850 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018851 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428852}
8853
bncd16676a2016-07-20 16:23:018854TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478855 HttpRequestInfo request;
8856 request.method = "GET";
bncce36dca22015-04-21 22:11:238857 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438858 request.extra_headers.SetHeader("referer", "www.foo.com");
8859 request.extra_headers.SetHeader("hEllo", "Kitty");
8860 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478861
danakj1fd259a02016-04-16 03:17:098862 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278864
[email protected]270c6412010-03-29 22:02:478865 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238866 MockWrite(
8867 "GET / HTTP/1.1\r\n"
8868 "Host: www.example.org\r\n"
8869 "Connection: keep-alive\r\n"
8870 "referer: www.foo.com\r\n"
8871 "hEllo: Kitty\r\n"
8872 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478873 };
8874
8875 // Lastly, the server responds with the actual content.
8876 MockRead data_reads[] = {
8877 MockRead("HTTP/1.0 200 OK\r\n"),
8878 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8879 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068880 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478881 };
8882
8883 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8884 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078885 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478886
[email protected]49639fa2011-12-20 23:22:418887 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478888
tfarina42834112016-09-22 13:38:208889 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478891
8892 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018893 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478894}
8895
bncd16676a2016-07-20 16:23:018896TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278897 HttpRequestInfo request;
8898 request.method = "GET";
bncce36dca22015-04-21 22:11:238899 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278900
rdsmith82957ad2015-09-16 19:42:038901 session_deps_.proxy_service =
8902 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518903 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078904 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028905
danakj1fd259a02016-04-16 03:17:098906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028908
[email protected]3cd17242009-06-23 02:59:028909 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8910 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8911
8912 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238913 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8914 MockWrite(
8915 "GET / HTTP/1.1\r\n"
8916 "Host: www.example.org\r\n"
8917 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028918
8919 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068920 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028921 MockRead("HTTP/1.0 200 OK\r\n"),
8922 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8923 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068924 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028925 };
8926
[email protected]31a2bfe2010-02-09 08:03:398927 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8928 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078929 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028930
[email protected]49639fa2011-12-20 23:22:418931 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028932
tfarina42834112016-09-22 13:38:208933 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028935
8936 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018937 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028938
bnc691fda62016-08-12 00:43:168939 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528940 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028941
tbansal2ecbbc72016-10-06 17:15:478942 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208943 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168944 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208945 TestLoadTimingNotReusedWithPac(load_timing_info,
8946 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8947
[email protected]3cd17242009-06-23 02:59:028948 std::string response_text;
bnc691fda62016-08-12 00:43:168949 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018950 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028951 EXPECT_EQ("Payload", response_text);
8952}
8953
bncd16676a2016-07-20 16:23:018954TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278955 HttpRequestInfo request;
8956 request.method = "GET";
bncce36dca22015-04-21 22:11:238957 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278958
rdsmith82957ad2015-09-16 19:42:038959 session_deps_.proxy_service =
8960 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518961 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078962 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028963
danakj1fd259a02016-04-16 03:17:098964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028966
[email protected]3cd17242009-06-23 02:59:028967 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8968 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8969
8970 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238971 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8972 arraysize(write_buffer)),
8973 MockWrite(
8974 "GET / HTTP/1.1\r\n"
8975 "Host: www.example.org\r\n"
8976 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028977
8978 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018979 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8980 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358981 MockRead("HTTP/1.0 200 OK\r\n"),
8982 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8983 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068984 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358985 };
8986
[email protected]31a2bfe2010-02-09 08:03:398987 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8988 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078989 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358990
[email protected]8ddf8322012-02-23 18:08:068991 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078992 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358993
[email protected]49639fa2011-12-20 23:22:418994 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358995
tfarina42834112016-09-22 13:38:208996 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358998
8999 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019000 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359001
[email protected]029c83b62013-01-24 05:28:209002 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169003 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209004 TestLoadTimingNotReusedWithPac(load_timing_info,
9005 CONNECT_TIMING_HAS_SSL_TIMES);
9006
bnc691fda62016-08-12 00:43:169007 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529008 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479009 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359010
9011 std::string response_text;
bnc691fda62016-08-12 00:43:169012 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019013 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359014 EXPECT_EQ("Payload", response_text);
9015}
9016
bncd16676a2016-07-20 16:23:019017TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209018 HttpRequestInfo request;
9019 request.method = "GET";
bncce36dca22015-04-21 22:11:239020 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209021
rdsmith82957ad2015-09-16 19:42:039022 session_deps_.proxy_service =
9023 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519024 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079025 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209026
danakj1fd259a02016-04-16 03:17:099027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169028 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209029
9030 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9031 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9032
9033 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239034 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9035 MockWrite(
9036 "GET / HTTP/1.1\r\n"
9037 "Host: www.example.org\r\n"
9038 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209039
9040 MockRead data_reads[] = {
9041 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9042 MockRead("HTTP/1.0 200 OK\r\n"),
9043 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9044 MockRead("Payload"),
9045 MockRead(SYNCHRONOUS, OK)
9046 };
9047
9048 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9049 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079050 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209051
9052 TestCompletionCallback callback;
9053
tfarina42834112016-09-22 13:38:209054 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209056
9057 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019058 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209059
bnc691fda62016-08-12 00:43:169060 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529061 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209062
9063 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169064 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209065 TestLoadTimingNotReused(load_timing_info,
9066 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9067
9068 std::string response_text;
bnc691fda62016-08-12 00:43:169069 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019070 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209071 EXPECT_EQ("Payload", response_text);
9072}
9073
bncd16676a2016-07-20 16:23:019074TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279075 HttpRequestInfo request;
9076 request.method = "GET";
bncce36dca22015-04-21 22:11:239077 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279078
rdsmith82957ad2015-09-16 19:42:039079 session_deps_.proxy_service =
9080 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519081 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079082 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359083
danakj1fd259a02016-04-16 03:17:099084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359086
[email protected]e0c27be2009-07-15 13:09:359087 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9088 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379089 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239090 0x05, // Version
9091 0x01, // Command (CONNECT)
9092 0x00, // Reserved.
9093 0x03, // Address type (DOMAINNAME).
9094 0x0F, // Length of domain (15)
9095 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9096 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379097 };
[email protected]e0c27be2009-07-15 13:09:359098 const char kSOCKS5OkResponse[] =
9099 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9100
9101 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239102 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9103 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9104 MockWrite(
9105 "GET / HTTP/1.1\r\n"
9106 "Host: www.example.org\r\n"
9107 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359108
9109 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019110 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9111 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359112 MockRead("HTTP/1.0 200 OK\r\n"),
9113 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9114 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069115 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359116 };
9117
[email protected]31a2bfe2010-02-09 08:03:399118 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9119 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079120 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359121
[email protected]49639fa2011-12-20 23:22:419122 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359123
tfarina42834112016-09-22 13:38:209124 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359126
9127 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019128 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359129
bnc691fda62016-08-12 00:43:169130 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529131 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479132 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359133
[email protected]029c83b62013-01-24 05:28:209134 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169135 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209136 TestLoadTimingNotReusedWithPac(load_timing_info,
9137 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9138
[email protected]e0c27be2009-07-15 13:09:359139 std::string response_text;
bnc691fda62016-08-12 00:43:169140 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019141 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359142 EXPECT_EQ("Payload", response_text);
9143}
9144
bncd16676a2016-07-20 16:23:019145TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279146 HttpRequestInfo request;
9147 request.method = "GET";
bncce36dca22015-04-21 22:11:239148 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279149
rdsmith82957ad2015-09-16 19:42:039150 session_deps_.proxy_service =
9151 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519152 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079153 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359154
danakj1fd259a02016-04-16 03:17:099155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359157
[email protected]e0c27be2009-07-15 13:09:359158 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9159 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379160 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239161 0x05, // Version
9162 0x01, // Command (CONNECT)
9163 0x00, // Reserved.
9164 0x03, // Address type (DOMAINNAME).
9165 0x0F, // Length of domain (15)
9166 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9167 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379168 };
9169
[email protected]e0c27be2009-07-15 13:09:359170 const char kSOCKS5OkResponse[] =
9171 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9172
9173 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239174 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9175 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9176 arraysize(kSOCKS5OkRequest)),
9177 MockWrite(
9178 "GET / HTTP/1.1\r\n"
9179 "Host: www.example.org\r\n"
9180 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359181
9182 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019183 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9184 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029185 MockRead("HTTP/1.0 200 OK\r\n"),
9186 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9187 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069188 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029189 };
9190
[email protected]31a2bfe2010-02-09 08:03:399191 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9192 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079193 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029194
[email protected]8ddf8322012-02-23 18:08:069195 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029197
[email protected]49639fa2011-12-20 23:22:419198 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029199
tfarina42834112016-09-22 13:38:209200 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019201 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029202
9203 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019204 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029205
bnc691fda62016-08-12 00:43:169206 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529207 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479208 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029209
[email protected]029c83b62013-01-24 05:28:209210 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169211 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209212 TestLoadTimingNotReusedWithPac(load_timing_info,
9213 CONNECT_TIMING_HAS_SSL_TIMES);
9214
[email protected]3cd17242009-06-23 02:59:029215 std::string response_text;
bnc691fda62016-08-12 00:43:169216 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019217 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029218 EXPECT_EQ("Payload", response_text);
9219}
9220
[email protected]448d4ca52012-03-04 04:12:239221namespace {
9222
[email protected]04e5be32009-06-26 20:00:319223// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069224
9225struct GroupNameTest {
9226 std::string proxy_server;
9227 std::string url;
9228 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189229 bool ssl;
[email protected]2d731a32010-04-29 01:04:069230};
9231
danakj1fd259a02016-04-16 03:17:099232std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079233 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099234 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069235
bnc525e175a2016-06-20 12:36:409236 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539237 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219238 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129239 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229240 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429241 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469242 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069243
9244 return session;
9245}
9246
mmenkee65e7af2015-10-13 17:16:429247int GroupNameTransactionHelper(const std::string& url,
9248 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069249 HttpRequestInfo request;
9250 request.method = "GET";
9251 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069252
bnc691fda62016-08-12 00:43:169253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279254
[email protected]49639fa2011-12-20 23:22:419255 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069256
9257 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209258 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069259}
9260
[email protected]448d4ca52012-03-04 04:12:239261} // namespace
9262
bncd16676a2016-07-20 16:23:019263TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069264 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239265 {
9266 "", // unused
9267 "http://www.example.org/direct",
9268 "www.example.org:80",
9269 false,
9270 },
9271 {
9272 "", // unused
9273 "http://[2001:1418:13:1::25]/direct",
9274 "[2001:1418:13:1::25]:80",
9275 false,
9276 },
[email protected]04e5be32009-06-26 20:00:319277
bncce36dca22015-04-21 22:11:239278 // SSL Tests
9279 {
9280 "", // unused
9281 "https://www.example.org/direct_ssl",
9282 "ssl/www.example.org:443",
9283 true,
9284 },
9285 {
9286 "", // unused
9287 "https://[2001:1418:13:1::25]/direct",
9288 "ssl/[2001:1418:13:1::25]:443",
9289 true,
9290 },
9291 {
9292 "", // unused
bncaa60ff402016-06-22 19:12:429293 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239294 "ssl/host.with.alternate:443",
9295 true,
9296 },
[email protected]2d731a32010-04-29 01:04:069297 };
[email protected]2ff8b312010-04-26 22:20:549298
viettrungluue4a8b882014-10-16 06:17:389299 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039300 session_deps_.proxy_service =
9301 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099302 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409303 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069304
mmenkee65e7af2015-10-13 17:16:429305 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289306 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589307 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139308 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589309 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
9310 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029311 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9312 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489313 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069314
9315 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429316 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189317 if (tests[i].ssl)
9318 EXPECT_EQ(tests[i].expected_group_name,
9319 ssl_conn_pool->last_group_name_received());
9320 else
9321 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289322 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069323 }
[email protected]2d731a32010-04-29 01:04:069324}
9325
bncd16676a2016-07-20 16:23:019326TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069327 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239328 {
9329 "http_proxy",
9330 "http://www.example.org/http_proxy_normal",
9331 "www.example.org:80",
9332 false,
9333 },
[email protected]2d731a32010-04-29 01:04:069334
bncce36dca22015-04-21 22:11:239335 // SSL Tests
9336 {
9337 "http_proxy",
9338 "https://www.example.org/http_connect_ssl",
9339 "ssl/www.example.org:443",
9340 true,
9341 },
[email protected]af3490e2010-10-16 21:02:299342
bncce36dca22015-04-21 22:11:239343 {
9344 "http_proxy",
bncaa60ff402016-06-22 19:12:429345 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239346 "ssl/host.with.alternate:443",
9347 true,
9348 },
[email protected]45499252013-01-23 17:12:569349
bncce36dca22015-04-21 22:11:239350 {
9351 "http_proxy",
9352 "ftp://ftp.google.com/http_proxy_normal",
9353 "ftp/ftp.google.com:21",
9354 false,
9355 },
[email protected]2d731a32010-04-29 01:04:069356 };
9357
viettrungluue4a8b882014-10-16 06:17:389358 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039359 session_deps_.proxy_service =
9360 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099361 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409362 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069363
mmenkee65e7af2015-10-13 17:16:429364 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069365
[email protected]e60e47a2010-07-14 03:37:189366 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139367 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349368 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139369 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349370 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589371 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399372 mock_pool_manager->SetSocketPoolForHTTPProxy(
9373 proxy_host, base::WrapUnique(http_proxy_pool));
9374 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9375 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489376 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069377
9378 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429379 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189380 if (tests[i].ssl)
9381 EXPECT_EQ(tests[i].expected_group_name,
9382 ssl_conn_pool->last_group_name_received());
9383 else
9384 EXPECT_EQ(tests[i].expected_group_name,
9385 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069386 }
[email protected]2d731a32010-04-29 01:04:069387}
9388
bncd16676a2016-07-20 16:23:019389TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069390 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239391 {
9392 "socks4://socks_proxy:1080",
9393 "http://www.example.org/socks4_direct",
9394 "socks4/www.example.org:80",
9395 false,
9396 },
9397 {
9398 "socks5://socks_proxy:1080",
9399 "http://www.example.org/socks5_direct",
9400 "socks5/www.example.org:80",
9401 false,
9402 },
[email protected]2d731a32010-04-29 01:04:069403
bncce36dca22015-04-21 22:11:239404 // SSL Tests
9405 {
9406 "socks4://socks_proxy:1080",
9407 "https://www.example.org/socks4_ssl",
9408 "socks4/ssl/www.example.org:443",
9409 true,
9410 },
9411 {
9412 "socks5://socks_proxy:1080",
9413 "https://www.example.org/socks5_ssl",
9414 "socks5/ssl/www.example.org:443",
9415 true,
9416 },
[email protected]af3490e2010-10-16 21:02:299417
bncce36dca22015-04-21 22:11:239418 {
9419 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429420 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239421 "socks4/ssl/host.with.alternate:443",
9422 true,
9423 },
[email protected]04e5be32009-06-26 20:00:319424 };
9425
viettrungluue4a8b882014-10-16 06:17:389426 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039427 session_deps_.proxy_service =
9428 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099429 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409430 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029431
mmenkee65e7af2015-10-13 17:16:429432 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319433
[email protected]e60e47a2010-07-14 03:37:189434 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139435 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349436 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139437 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349438 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589439 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399440 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9441 proxy_host, base::WrapUnique(socks_conn_pool));
9442 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9443 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489444 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319445
bnc691fda62016-08-12 00:43:169446 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319447
[email protected]2d731a32010-04-29 01:04:069448 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429449 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189450 if (tests[i].ssl)
9451 EXPECT_EQ(tests[i].expected_group_name,
9452 ssl_conn_pool->last_group_name_received());
9453 else
9454 EXPECT_EQ(tests[i].expected_group_name,
9455 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319456 }
9457}
9458
bncd16676a2016-07-20 16:23:019459TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279460 HttpRequestInfo request;
9461 request.method = "GET";
bncce36dca22015-04-21 22:11:239462 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279463
rdsmith82957ad2015-09-16 19:42:039464 session_deps_.proxy_service =
9465 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329466
[email protected]69719062010-01-05 20:09:219467 // This simulates failure resolving all hostnames; that means we will fail
9468 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079469 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329470
danakj1fd259a02016-04-16 03:17:099471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259473
[email protected]49639fa2011-12-20 23:22:419474 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259475
tfarina42834112016-09-22 13:38:209476 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259478
[email protected]9172a982009-06-06 00:30:259479 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019480 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259481}
9482
[email protected]685af592010-05-11 19:31:249483// Base test to make sure that when the load flags for a request specify to
9484// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029485void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079486 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279487 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109488 HttpRequestInfo request_info;
9489 request_info.method = "GET";
9490 request_info.load_flags = load_flags;
9491 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279492
[email protected]a2c2fb92009-07-18 07:31:049493 // Select a host resolver that does caching.
bnc87dcefc2017-05-25 12:47:589494 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329495
danakj1fd259a02016-04-16 03:17:099496 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289498
bncce36dca22015-04-21 22:11:239499 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289500 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299501 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109502 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079503 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239504 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109505 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209506 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479508 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019509 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289510
9511 // Verify that it was added to host cache, by doing a subsequent async lookup
9512 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109513 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079514 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239515 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109516 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209517 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019518 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289519
bncce36dca22015-04-21 22:11:239520 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289521 // we can tell if the next lookup hit the cache, or the "network".
9522 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239523 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289524
9525 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9526 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069527 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399528 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079529 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289530
[email protected]3b9cca42009-06-16 01:08:289531 // Run the request.
tfarina42834112016-09-22 13:38:209532 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019533 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419534 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289535
9536 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239537 // "www.example.org".
robpercival214763f2016-07-01 23:27:019538 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289539}
9540
[email protected]685af592010-05-11 19:31:249541// There are multiple load flags that should trigger the host cache bypass.
9542// Test each in isolation:
bncd16676a2016-07-20 16:23:019543TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249544 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9545}
9546
bncd16676a2016-07-20 16:23:019547TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249548 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9549}
9550
bncd16676a2016-07-20 16:23:019551TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249552 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9553}
9554
[email protected]0877e3d2009-10-17 22:29:579555// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019556TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579557 HttpRequestInfo request;
9558 request.method = "GET";
9559 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579560
9561 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069562 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579563 };
[email protected]31a2bfe2010-02-09 08:03:399564 StaticSocketDataProvider data(NULL, 0,
9565 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079566 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099567 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579568
[email protected]49639fa2011-12-20 23:22:419569 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579570
bnc691fda62016-08-12 00:43:169571 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579572
tfarina42834112016-09-22 13:38:209573 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579575
9576 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019577 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599578
9579 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169580 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599581 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579582}
9583
zmo9528c9f42015-08-04 22:12:089584// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019585TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579586 HttpRequestInfo request;
9587 request.method = "GET";
9588 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579589
9590 MockRead data_reads[] = {
9591 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069592 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579593 };
9594
[email protected]31a2bfe2010-02-09 08:03:399595 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079596 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099597 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579598
[email protected]49639fa2011-12-20 23:22:419599 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579600
bnc691fda62016-08-12 00:43:169601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579602
tfarina42834112016-09-22 13:38:209603 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579605
9606 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019607 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089608
bnc691fda62016-08-12 00:43:169609 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529610 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089611
wezca1070932016-05-26 20:30:529612 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089613 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9614
9615 std::string response_data;
bnc691fda62016-08-12 00:43:169616 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019617 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089618 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599619
9620 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169621 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599622 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579623}
9624
9625// Make sure that a dropped connection while draining the body for auth
9626// restart does the right thing.
bncd16676a2016-07-20 16:23:019627TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579628 HttpRequestInfo request;
9629 request.method = "GET";
bncce36dca22015-04-21 22:11:239630 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579631
9632 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239633 MockWrite(
9634 "GET / HTTP/1.1\r\n"
9635 "Host: www.example.org\r\n"
9636 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579637 };
9638
9639 MockRead data_reads1[] = {
9640 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9641 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9642 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9643 MockRead("Content-Length: 14\r\n\r\n"),
9644 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069645 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579646 };
9647
[email protected]31a2bfe2010-02-09 08:03:399648 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9649 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079650 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579651
bnc691fda62016-08-12 00:43:169652 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579653 // be issuing -- the final header line contains the credentials.
9654 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239655 MockWrite(
9656 "GET / HTTP/1.1\r\n"
9657 "Host: www.example.org\r\n"
9658 "Connection: keep-alive\r\n"
9659 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579660 };
9661
9662 // Lastly, the server responds with the actual content.
9663 MockRead data_reads2[] = {
9664 MockRead("HTTP/1.1 200 OK\r\n"),
9665 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9666 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069667 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579668 };
9669
[email protected]31a2bfe2010-02-09 08:03:399670 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9671 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079672 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579674
[email protected]49639fa2011-12-20 23:22:419675 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579676
bnc691fda62016-08-12 00:43:169677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509678
tfarina42834112016-09-22 13:38:209679 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579681
9682 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019683 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579684
bnc691fda62016-08-12 00:43:169685 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529686 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049687 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579688
[email protected]49639fa2011-12-20 23:22:419689 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579690
bnc691fda62016-08-12 00:43:169691 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579693
9694 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019695 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579696
bnc691fda62016-08-12 00:43:169697 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529698 ASSERT_TRUE(response);
9699 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579700 EXPECT_EQ(100, response->headers->GetContentLength());
9701}
9702
9703// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019704TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039705 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579706
9707 HttpRequestInfo request;
9708 request.method = "GET";
bncce36dca22015-04-21 22:11:239709 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579710
9711 MockRead proxy_reads[] = {
9712 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069713 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579714 };
9715
[email protected]31a2bfe2010-02-09 08:03:399716 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069717 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579718
[email protected]bb88e1d32013-05-03 23:11:079719 session_deps_.socket_factory->AddSocketDataProvider(&data);
9720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579721
[email protected]49639fa2011-12-20 23:22:419722 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579723
[email protected]bb88e1d32013-05-03 23:11:079724 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579725
danakj1fd259a02016-04-16 03:17:099726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169727 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579728
tfarina42834112016-09-22 13:38:209729 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579731
9732 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019733 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579734}
9735
bncd16676a2016-07-20 16:23:019736TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469737 HttpRequestInfo request;
9738 request.method = "GET";
bncce36dca22015-04-21 22:11:239739 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469740
danakj1fd259a02016-04-16 03:17:099741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279743
[email protected]e22e1362009-11-23 21:31:129744 MockRead data_reads[] = {
9745 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069746 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129747 };
[email protected]9492e4a2010-02-24 00:58:469748
9749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079750 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469751
[email protected]49639fa2011-12-20 23:22:419752 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469753
tfarina42834112016-09-22 13:38:209754 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469756
robpercival214763f2016-07-01 23:27:019757 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469758
bnc691fda62016-08-12 00:43:169759 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529760 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469761
wezca1070932016-05-26 20:30:529762 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469763 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9764
9765 std::string response_data;
bnc691fda62016-08-12 00:43:169766 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019767 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129768}
9769
bncd16676a2016-07-20 16:23:019770TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159771 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529772 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149773 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219774 UploadFileElementReader::ScopedOverridingContentLengthForTests
9775 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339776
danakj1fd259a02016-04-16 03:17:099777 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079778 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149779 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079780 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229781 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279782
9783 HttpRequestInfo request;
9784 request.method = "POST";
bncce36dca22015-04-21 22:11:239785 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279786 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279787
danakj1fd259a02016-04-16 03:17:099788 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169789 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339790
9791 MockRead data_reads[] = {
9792 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9793 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069794 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339795 };
[email protected]31a2bfe2010-02-09 08:03:399796 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079797 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339798
[email protected]49639fa2011-12-20 23:22:419799 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339800
tfarina42834112016-09-22 13:38:209801 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339803
9804 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019805 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339806
bnc691fda62016-08-12 00:43:169807 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529808 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339809
maksim.sisove869bf52016-06-23 17:11:529810 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339811
[email protected]dd3aa792013-07-16 19:10:239812 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339813}
9814
bncd16676a2016-07-20 16:23:019815TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159816 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529817 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369818 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:489819 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
9820 base::WriteFile(temp_file, temp_file_content.c_str(),
9821 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119822 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369823
danakj1fd259a02016-04-16 03:17:099824 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079825 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149826 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079827 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229828 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279829
9830 HttpRequestInfo request;
9831 request.method = "POST";
bncce36dca22015-04-21 22:11:239832 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279833 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279834
[email protected]999dd8c2013-11-12 06:45:549835 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369838
[email protected]999dd8c2013-11-12 06:45:549839 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079840 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369841
[email protected]49639fa2011-12-20 23:22:419842 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369843
tfarina42834112016-09-22 13:38:209844 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019845 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369846
9847 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019848 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369849
[email protected]dd3aa792013-07-16 19:10:239850 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369851}
9852
bncd16676a2016-07-20 16:23:019853TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039854 class FakeUploadElementReader : public UploadElementReader {
9855 public:
9856 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209857 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039858
9859 const CompletionCallback& callback() const { return callback_; }
9860
9861 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209862 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039863 callback_ = callback;
9864 return ERR_IO_PENDING;
9865 }
avibf0746c2015-12-09 19:53:149866 uint64_t GetContentLength() const override { return 0; }
9867 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209868 int Read(IOBuffer* buf,
9869 int buf_length,
9870 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039871 return ERR_FAILED;
9872 }
9873
9874 private:
9875 CompletionCallback callback_;
9876 };
9877
9878 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099879 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9880 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229881 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039882
9883 HttpRequestInfo request;
9884 request.method = "POST";
bncce36dca22015-04-21 22:11:239885 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039886 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039887
danakj1fd259a02016-04-16 03:17:099888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:589889 auto trans =
9890 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:039891
9892 StaticSocketDataProvider data;
9893 session_deps_.socket_factory->AddSocketDataProvider(&data);
9894
9895 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209896 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559898 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039899
9900 // Transaction is pending on request body initialization.
9901 ASSERT_FALSE(fake_reader->callback().is_null());
9902
9903 // Return Init()'s result after the transaction gets destroyed.
9904 trans.reset();
9905 fake_reader->callback().Run(OK); // Should not crash.
9906}
9907
[email protected]aeefc9e82010-02-19 16:18:279908// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019909TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279910 HttpRequestInfo request;
9911 request.method = "GET";
bncce36dca22015-04-21 22:11:239912 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279913
9914 // First transaction will request a resource and receive a Basic challenge
9915 // with realm="first_realm".
9916 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239917 MockWrite(
9918 "GET / HTTP/1.1\r\n"
9919 "Host: www.example.org\r\n"
9920 "Connection: keep-alive\r\n"
9921 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279922 };
9923 MockRead data_reads1[] = {
9924 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9925 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9926 "\r\n"),
9927 };
9928
bnc691fda62016-08-12 00:43:169929 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279930 // for first_realm. The server will reject and provide a challenge with
9931 // second_realm.
9932 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239933 MockWrite(
9934 "GET / HTTP/1.1\r\n"
9935 "Host: www.example.org\r\n"
9936 "Connection: keep-alive\r\n"
9937 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9938 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279939 };
9940 MockRead data_reads2[] = {
9941 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9942 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9943 "\r\n"),
9944 };
9945
9946 // This again fails, and goes back to first_realm. Make sure that the
9947 // entry is removed from cache.
9948 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239949 MockWrite(
9950 "GET / HTTP/1.1\r\n"
9951 "Host: www.example.org\r\n"
9952 "Connection: keep-alive\r\n"
9953 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9954 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279955 };
9956 MockRead data_reads3[] = {
9957 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9958 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9959 "\r\n"),
9960 };
9961
9962 // Try one last time (with the correct password) and get the resource.
9963 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239964 MockWrite(
9965 "GET / HTTP/1.1\r\n"
9966 "Host: www.example.org\r\n"
9967 "Connection: keep-alive\r\n"
9968 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9969 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279970 };
9971 MockRead data_reads4[] = {
9972 MockRead("HTTP/1.1 200 OK\r\n"
9973 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509974 "Content-Length: 5\r\n"
9975 "\r\n"
9976 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279977 };
9978
9979 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9980 data_writes1, arraysize(data_writes1));
9981 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9982 data_writes2, arraysize(data_writes2));
9983 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9984 data_writes3, arraysize(data_writes3));
9985 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9986 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079987 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9988 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9989 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9990 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279991
[email protected]49639fa2011-12-20 23:22:419992 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279993
danakj1fd259a02016-04-16 03:17:099994 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169995 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509996
[email protected]aeefc9e82010-02-19 16:18:279997 // Issue the first request with Authorize headers. There should be a
9998 // password prompt for first_realm waiting to be filled in after the
9999 // transaction completes.
tfarina42834112016-09-22 13:38:2010000 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710002 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110003 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610004 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210005 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410006 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210007 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410008 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310009 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410010 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910011 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710012
10013 // Issue the second request with an incorrect password. There should be a
10014 // password prompt for second_realm waiting to be filled in after the
10015 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110016 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610017 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10018 callback2.callback());
robpercival214763f2016-07-01 23:27:0110019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710020 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110021 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610022 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210023 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410024 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210025 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410026 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310027 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410028 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910029 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710030
10031 // Issue the third request with another incorrect password. There should be
10032 // a password prompt for first_realm waiting to be filled in. If the password
10033 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10034 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110035 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610036 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10037 callback3.callback());
robpercival214763f2016-07-01 23:27:0110038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710039 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110040 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610041 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210042 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410043 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210044 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410045 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310046 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410047 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910048 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710049
10050 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110051 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610052 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10053 callback4.callback());
robpercival214763f2016-07-01 23:27:0110054 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710055 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110056 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610057 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210058 ASSERT_TRUE(response);
10059 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710060}
10061
bncd16676a2016-07-20 16:23:0110062TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210063 MockRead data_reads[] = {
10064 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310065 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210066 MockRead("\r\n"),
10067 MockRead("hello world"),
10068 MockRead(SYNCHRONOUS, OK),
10069 };
10070
10071 HttpRequestInfo request;
10072 request.method = "GET";
bncb26024382016-06-29 02:39:4510073 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210074
10075 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210076 session_deps_.socket_factory->AddSocketDataProvider(&data);
10077
bncb26024382016-06-29 02:39:4510078 SSLSocketDataProvider ssl(ASYNC, OK);
10079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10080
bncc958faa2015-07-31 18:14:5210081 TestCompletionCallback callback;
10082
danakj1fd259a02016-04-16 03:17:0910083 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610084 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210085
tfarina42834112016-09-22 13:38:2010086 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210088
bncb26024382016-06-29 02:39:4510089 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010090 HttpServerProperties* http_server_properties =
10091 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410092 EXPECT_TRUE(
10093 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210094
robpercival214763f2016-07-01 23:27:0110095 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210096
bnc691fda62016-08-12 00:43:1610097 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210098 ASSERT_TRUE(response);
10099 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210100 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10101 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210102 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210103
10104 std::string response_data;
bnc691fda62016-08-12 00:43:1610105 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210106 EXPECT_EQ("hello world", response_data);
10107
zhongyic4de03032017-05-19 04:07:3410108 AlternativeServiceInfoVector alternative_service_info_vector =
10109 http_server_properties->GetAlternativeServiceInfos(test_server);
10110 ASSERT_EQ(1u, alternative_service_info_vector.size());
10111 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10112 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410113 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210114}
10115
bnce3dd56f2016-06-01 10:37:1110116// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110117TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110118 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110119 MockRead data_reads[] = {
10120 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310121 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110122 MockRead("\r\n"),
10123 MockRead("hello world"),
10124 MockRead(SYNCHRONOUS, OK),
10125 };
10126
10127 HttpRequestInfo request;
10128 request.method = "GET";
10129 request.url = GURL("http://www.example.org/");
10130 request.load_flags = 0;
10131
10132 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10133 session_deps_.socket_factory->AddSocketDataProvider(&data);
10134
10135 TestCompletionCallback callback;
10136
10137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610138 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110139
10140 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010141 HttpServerProperties* http_server_properties =
10142 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410143 EXPECT_TRUE(
10144 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110145
tfarina42834112016-09-22 13:38:2010146 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110147 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10148 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110149
bnc691fda62016-08-12 00:43:1610150 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110151 ASSERT_TRUE(response);
10152 ASSERT_TRUE(response->headers);
10153 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10154 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210155 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110156
10157 std::string response_data;
bnc691fda62016-08-12 00:43:1610158 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110159 EXPECT_EQ("hello world", response_data);
10160
zhongyic4de03032017-05-19 04:07:3410161 EXPECT_TRUE(
10162 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110163}
10164
bnca86731e2017-04-17 12:31:2810165// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510166// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110167TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510168 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810169 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510170
bnc8bef8da22016-05-30 01:28:2510171 HttpRequestInfo request;
10172 request.method = "GET";
bncb26024382016-06-29 02:39:4510173 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510174 request.load_flags = 0;
10175
10176 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10177 StaticSocketDataProvider first_data;
10178 first_data.set_connect_data(mock_connect);
10179 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510180 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610181 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510183
10184 MockRead data_reads[] = {
10185 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10186 MockRead(ASYNC, OK),
10187 };
10188 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10189 0);
10190 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10191
10192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10193
bnc525e175a2016-06-20 12:36:4010194 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510195 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110196 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10197 444);
bnc8bef8da22016-05-30 01:28:2510198 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10199 http_server_properties->SetAlternativeService(
10200 url::SchemeHostPort(request.url), alternative_service, expiration);
10201
bnc691fda62016-08-12 00:43:1610202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510203 TestCompletionCallback callback;
10204
tfarina42834112016-09-22 13:38:2010205 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510206 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110207 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510208}
10209
bnce3dd56f2016-06-01 10:37:1110210// Regression test for https://crbug.com/615497:
10211// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110212TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110213 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110214 HttpRequestInfo request;
10215 request.method = "GET";
10216 request.url = GURL("http://www.example.org/");
10217 request.load_flags = 0;
10218
10219 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10220 StaticSocketDataProvider first_data;
10221 first_data.set_connect_data(mock_connect);
10222 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10223
10224 MockRead data_reads[] = {
10225 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10226 MockRead(ASYNC, OK),
10227 };
10228 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10229 0);
10230 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10231
10232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10233
bnc525e175a2016-06-20 12:36:4010234 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110235 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110236 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110237 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10238 http_server_properties->SetAlternativeService(
10239 url::SchemeHostPort(request.url), alternative_service, expiration);
10240
bnc691fda62016-08-12 00:43:1610241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110242 TestCompletionCallback callback;
10243
tfarina42834112016-09-22 13:38:2010244 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110245 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110246 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110247}
10248
bncd16676a2016-07-20 16:23:0110249TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810250 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910251 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010252 HttpServerProperties* http_server_properties =
10253 session->http_server_properties();
bncb26024382016-06-29 02:39:4510254 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110255 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810256 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010257 http_server_properties->SetAlternativeService(
10258 test_server, alternative_service, expiration);
zhongyic4de03032017-05-19 04:07:3410259 EXPECT_EQ(
10260 1u,
10261 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810262
10263 // Send a clear header.
10264 MockRead data_reads[] = {
10265 MockRead("HTTP/1.1 200 OK\r\n"),
10266 MockRead("Alt-Svc: clear\r\n"),
10267 MockRead("\r\n"),
10268 MockRead("hello world"),
10269 MockRead(SYNCHRONOUS, OK),
10270 };
10271 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10272 session_deps_.socket_factory->AddSocketDataProvider(&data);
10273
bncb26024382016-06-29 02:39:4510274 SSLSocketDataProvider ssl(ASYNC, OK);
10275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10276
bnc4f575852015-10-14 18:35:0810277 HttpRequestInfo request;
10278 request.method = "GET";
bncb26024382016-06-29 02:39:4510279 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810280
10281 TestCompletionCallback callback;
10282
bnc691fda62016-08-12 00:43:1610283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810284
tfarina42834112016-09-22 13:38:2010285 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110286 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810287
bnc691fda62016-08-12 00:43:1610288 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210289 ASSERT_TRUE(response);
10290 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810291 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10292 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210293 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810294
10295 std::string response_data;
bnc691fda62016-08-12 00:43:1610296 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810297 EXPECT_EQ("hello world", response_data);
10298
zhongyic4de03032017-05-19 04:07:3410299 EXPECT_TRUE(
10300 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810301}
10302
bncd16676a2016-07-20 16:23:0110303TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210304 MockRead data_reads[] = {
10305 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310306 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10307 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210308 MockRead("hello world"),
10309 MockRead(SYNCHRONOUS, OK),
10310 };
10311
10312 HttpRequestInfo request;
10313 request.method = "GET";
bncb26024382016-06-29 02:39:4510314 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210315
10316 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210317 session_deps_.socket_factory->AddSocketDataProvider(&data);
10318
bncb26024382016-06-29 02:39:4510319 SSLSocketDataProvider ssl(ASYNC, OK);
10320 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10321
bncc958faa2015-07-31 18:14:5210322 TestCompletionCallback callback;
10323
danakj1fd259a02016-04-16 03:17:0910324 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210326
tfarina42834112016-09-22 13:38:2010327 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210329
bncb26024382016-06-29 02:39:4510330 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010331 HttpServerProperties* http_server_properties =
10332 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410333 EXPECT_TRUE(
10334 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210335
robpercival214763f2016-07-01 23:27:0110336 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210337
bnc691fda62016-08-12 00:43:1610338 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210339 ASSERT_TRUE(response);
10340 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210341 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10342 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210343 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210344
10345 std::string response_data;
bnc691fda62016-08-12 00:43:1610346 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210347 EXPECT_EQ("hello world", response_data);
10348
zhongyic4de03032017-05-19 04:07:3410349 AlternativeServiceInfoVector alternative_service_info_vector =
10350 http_server_properties->GetAlternativeServiceInfos(test_server);
10351 ASSERT_EQ(2u, alternative_service_info_vector.size());
10352
10353 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
10354 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410355 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410356 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10357 1234);
10358 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5410359 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5210360}
10361
bncd16676a2016-07-20 16:23:0110362TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610363 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210364 HostPortPair alternative("alternative.example.org", 443);
10365 std::string origin_url = "https://origin.example.org:443";
10366 std::string alternative_url = "https://alternative.example.org:443";
10367
10368 // Negotiate HTTP/1.1 with alternative.example.org.
10369 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610370 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10372
10373 // HTTP/1.1 data for request.
10374 MockWrite http_writes[] = {
10375 MockWrite("GET / HTTP/1.1\r\n"
10376 "Host: alternative.example.org\r\n"
10377 "Connection: keep-alive\r\n\r\n"),
10378 };
10379
10380 MockRead http_reads[] = {
10381 MockRead("HTTP/1.1 200 OK\r\n"
10382 "Content-Type: text/html; charset=iso-8859-1\r\n"
10383 "Content-Length: 40\r\n\r\n"
10384 "first HTTP/1.1 response from alternative"),
10385 };
10386 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10387 http_writes, arraysize(http_writes));
10388 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10389
10390 StaticSocketDataProvider data_refused;
10391 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10392 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10393
zhongyi3d4a55e72016-04-22 20:36:4610394 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010396 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210397 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110398 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210399 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610400 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010401 expiration);
zhongyi48704c182015-12-07 07:52:0210402 // Mark the QUIC alternative service as broken.
10403 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10404
zhongyi48704c182015-12-07 07:52:0210405 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210407 request.method = "GET";
10408 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210409 TestCompletionCallback callback;
10410 NetErrorDetails details;
10411 EXPECT_FALSE(details.quic_broken);
10412
tfarina42834112016-09-22 13:38:2010413 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610414 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210415 EXPECT_TRUE(details.quic_broken);
10416}
10417
bncd16676a2016-07-20 16:23:0110418TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610419 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210420 HostPortPair alternative1("alternative1.example.org", 443);
10421 HostPortPair alternative2("alternative2.example.org", 443);
10422 std::string origin_url = "https://origin.example.org:443";
10423 std::string alternative_url1 = "https://alternative1.example.org:443";
10424 std::string alternative_url2 = "https://alternative2.example.org:443";
10425
10426 // Negotiate HTTP/1.1 with alternative1.example.org.
10427 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610428 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10430
10431 // HTTP/1.1 data for request.
10432 MockWrite http_writes[] = {
10433 MockWrite("GET / HTTP/1.1\r\n"
10434 "Host: alternative1.example.org\r\n"
10435 "Connection: keep-alive\r\n\r\n"),
10436 };
10437
10438 MockRead http_reads[] = {
10439 MockRead("HTTP/1.1 200 OK\r\n"
10440 "Content-Type: text/html; charset=iso-8859-1\r\n"
10441 "Content-Length: 40\r\n\r\n"
10442 "first HTTP/1.1 response from alternative1"),
10443 };
10444 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10445 http_writes, arraysize(http_writes));
10446 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10447
10448 StaticSocketDataProvider data_refused;
10449 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10450 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10451
danakj1fd259a02016-04-16 03:17:0910452 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010453 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210454 session->http_server_properties();
10455
zhongyi3d4a55e72016-04-22 20:36:4610456 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210457 AlternativeServiceInfoVector alternative_service_info_vector;
10458 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10459
bnc3472afd2016-11-17 15:27:2110460 AlternativeService alternative_service1(kProtoQUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010461 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210462 expiration);
10463 alternative_service_info_vector.push_back(alternative_service_info1);
bnc3472afd2016-11-17 15:27:2110464 AlternativeService alternative_service2(kProtoQUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010465 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210466 expiration);
10467 alternative_service_info_vector.push_back(alternative_service_info2);
10468
10469 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610470 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210471
10472 // Mark one of the QUIC alternative service as broken.
10473 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410474 EXPECT_EQ(2u,
10475 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210476
zhongyi48704c182015-12-07 07:52:0210477 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610478 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210479 request.method = "GET";
10480 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210481 TestCompletionCallback callback;
10482 NetErrorDetails details;
10483 EXPECT_FALSE(details.quic_broken);
10484
tfarina42834112016-09-22 13:38:2010485 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610486 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210487 EXPECT_FALSE(details.quic_broken);
10488}
10489
bncd16676a2016-07-20 16:23:0110490TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210491 HttpRequestInfo request;
10492 request.method = "GET";
bncb26024382016-06-29 02:39:4510493 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210494
[email protected]d973e99a2012-02-17 21:02:3610495 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210496 StaticSocketDataProvider first_data;
10497 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710498 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510499 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610500 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210502
10503 MockRead data_reads[] = {
10504 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10505 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610506 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210507 };
10508 StaticSocketDataProvider second_data(
10509 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710510 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210511
danakj1fd259a02016-04-16 03:17:0910512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210513
bnc525e175a2016-06-20 12:36:4010514 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310515 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610516 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110517 // Port must be < 1024, or the header will be ignored (since initial port was
10518 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010519 const AlternativeService alternative_service(
bnc3472afd2016-11-17 15:27:2110520 kProtoHTTP2, "www.example.org",
bncd9b132e2015-07-08 05:16:1010521 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210522 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610523 http_server_properties->SetAlternativeService(server, alternative_service,
10524 expiration);
[email protected]564b4912010-03-09 16:30:4210525
bnc691fda62016-08-12 00:43:1610526 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110527 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210528
tfarina42834112016-09-22 13:38:2010529 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10531 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210532
bnc691fda62016-08-12 00:43:1610533 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210534 ASSERT_TRUE(response);
10535 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210536 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10537
10538 std::string response_data;
bnc691fda62016-08-12 00:43:1610539 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210540 EXPECT_EQ("hello world", response_data);
10541
zhongyic4de03032017-05-19 04:07:3410542 const AlternativeServiceInfoVector alternative_service_info_vector =
10543 http_server_properties->GetAlternativeServiceInfos(server);
10544 ASSERT_EQ(1u, alternative_service_info_vector.size());
10545 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410546 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410547 EXPECT_TRUE(
10548 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210549}
10550
bnc55ff9da2015-08-19 18:42:3510551// Ensure that we are not allowed to redirect traffic via an alternate protocol
10552// to an unrestricted (port >= 1024) when the original traffic was on a
10553// restricted port (port < 1024). Ensure that we can redirect in all other
10554// cases.
bncd16676a2016-07-20 16:23:0110555TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110556 HttpRequestInfo restricted_port_request;
10557 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510558 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110559 restricted_port_request.load_flags = 0;
10560
[email protected]d973e99a2012-02-17 21:02:3610561 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110562 StaticSocketDataProvider first_data;
10563 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710564 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110565
10566 MockRead data_reads[] = {
10567 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10568 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610569 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110570 };
10571 StaticSocketDataProvider second_data(
10572 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710573 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510574 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610575 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110577
danakj1fd259a02016-04-16 03:17:0910578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110579
bnc525e175a2016-06-20 12:36:4010580 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310581 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110582 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110583 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10584 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210585 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210586 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610587 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010588 expiration);
[email protected]3912662a32011-10-04 00:51:1110589
bnc691fda62016-08-12 00:43:1610590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110591 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110592
tfarina42834112016-09-22 13:38:2010593 int rv = trans.Start(&restricted_port_request, callback.callback(),
10594 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110596 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110597 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910598}
[email protected]3912662a32011-10-04 00:51:1110599
bnc55ff9da2015-08-19 18:42:3510600// Ensure that we are allowed to redirect traffic via an alternate protocol to
10601// an unrestricted (port >= 1024) when the original traffic was on a restricted
10602// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110603TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710604 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910605
10606 HttpRequestInfo restricted_port_request;
10607 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510608 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910609 restricted_port_request.load_flags = 0;
10610
10611 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10612 StaticSocketDataProvider first_data;
10613 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710614 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910615
10616 MockRead data_reads[] = {
10617 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10618 MockRead("hello world"),
10619 MockRead(ASYNC, OK),
10620 };
10621 StaticSocketDataProvider second_data(
10622 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710623 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510624 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610625 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910627
danakj1fd259a02016-04-16 03:17:0910628 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910629
bnc525e175a2016-06-20 12:36:4010630 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910631 session->http_server_properties();
10632 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110633 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10634 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210635 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210636 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610637 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010638 expiration);
[email protected]c54c6962013-02-01 04:53:1910639
bnc691fda62016-08-12 00:43:1610640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910641 TestCompletionCallback callback;
10642
tfarina42834112016-09-22 13:38:2010643 EXPECT_EQ(ERR_IO_PENDING,
10644 trans.Start(&restricted_port_request, callback.callback(),
10645 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910646 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110647 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110648}
10649
bnc55ff9da2015-08-19 18:42:3510650// Ensure that we are not allowed to redirect traffic via an alternate protocol
10651// to an unrestricted (port >= 1024) when the original traffic was on a
10652// restricted port (port < 1024). Ensure that we can redirect in all other
10653// cases.
bncd16676a2016-07-20 16:23:0110654TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110655 HttpRequestInfo restricted_port_request;
10656 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510657 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110658 restricted_port_request.load_flags = 0;
10659
[email protected]d973e99a2012-02-17 21:02:3610660 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110661 StaticSocketDataProvider first_data;
10662 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710663 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110664
10665 MockRead data_reads[] = {
10666 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10667 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610668 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110669 };
10670 StaticSocketDataProvider second_data(
10671 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710672 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110673
bncb26024382016-06-29 02:39:4510674 SSLSocketDataProvider ssl(ASYNC, OK);
10675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10676
danakj1fd259a02016-04-16 03:17:0910677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110678
bnc525e175a2016-06-20 12:36:4010679 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310680 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110681 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110682 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10683 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210684 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210685 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610686 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010687 expiration);
[email protected]3912662a32011-10-04 00:51:1110688
bnc691fda62016-08-12 00:43:1610689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110690 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110691
tfarina42834112016-09-22 13:38:2010692 int rv = trans.Start(&restricted_port_request, callback.callback(),
10693 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110695 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110696 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110697}
10698
bnc55ff9da2015-08-19 18:42:3510699// Ensure that we are not allowed to redirect traffic via an alternate protocol
10700// to an unrestricted (port >= 1024) when the original traffic was on a
10701// restricted port (port < 1024). Ensure that we can redirect in all other
10702// cases.
bncd16676a2016-07-20 16:23:0110703TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110704 HttpRequestInfo unrestricted_port_request;
10705 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510706 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110707 unrestricted_port_request.load_flags = 0;
10708
[email protected]d973e99a2012-02-17 21:02:3610709 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110710 StaticSocketDataProvider first_data;
10711 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710712 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110713
10714 MockRead data_reads[] = {
10715 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10716 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610717 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110718 };
10719 StaticSocketDataProvider second_data(
10720 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710721 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510722 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610723 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110725
danakj1fd259a02016-04-16 03:17:0910726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110727
bnc525e175a2016-06-20 12:36:4010728 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310729 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110730 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110731 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10732 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210733 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210734 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610735 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010736 expiration);
[email protected]3912662a32011-10-04 00:51:1110737
bnc691fda62016-08-12 00:43:1610738 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110739 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110740
bnc691fda62016-08-12 00:43:1610741 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010742 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110744 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110745 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110746}
10747
bnc55ff9da2015-08-19 18:42:3510748// Ensure that we are not allowed to redirect traffic via an alternate protocol
10749// to an unrestricted (port >= 1024) when the original traffic was on a
10750// restricted port (port < 1024). Ensure that we can redirect in all other
10751// cases.
bncd16676a2016-07-20 16:23:0110752TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110753 HttpRequestInfo unrestricted_port_request;
10754 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510755 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110756 unrestricted_port_request.load_flags = 0;
10757
[email protected]d973e99a2012-02-17 21:02:3610758 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110759 StaticSocketDataProvider first_data;
10760 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710761 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110762
10763 MockRead data_reads[] = {
10764 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10765 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610766 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110767 };
10768 StaticSocketDataProvider second_data(
10769 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710770 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110771
bncb26024382016-06-29 02:39:4510772 SSLSocketDataProvider ssl(ASYNC, OK);
10773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10774
danakj1fd259a02016-04-16 03:17:0910775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110776
bnc525e175a2016-06-20 12:36:4010777 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310778 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210779 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110780 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10781 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210782 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210783 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610784 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010785 expiration);
[email protected]3912662a32011-10-04 00:51:1110786
bnc691fda62016-08-12 00:43:1610787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110788 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110789
bnc691fda62016-08-12 00:43:1610790 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010791 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110793 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110794 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110795}
10796
bnc55ff9da2015-08-19 18:42:3510797// Ensure that we are not allowed to redirect traffic via an alternate protocol
10798// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10799// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110800TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210801 HttpRequestInfo request;
10802 request.method = "GET";
bncce36dca22015-04-21 22:11:2310803 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210804
10805 // The alternate protocol request will error out before we attempt to connect,
10806 // so only the standard HTTP request will try to connect.
10807 MockRead data_reads[] = {
10808 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10809 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610810 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210811 };
10812 StaticSocketDataProvider data(
10813 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710814 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210815
danakj1fd259a02016-04-16 03:17:0910816 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210817
bnc525e175a2016-06-20 12:36:4010818 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210819 session->http_server_properties();
10820 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110821 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10822 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210823 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210824 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610825 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210826
bnc691fda62016-08-12 00:43:1610827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210828 TestCompletionCallback callback;
10829
tfarina42834112016-09-22 13:38:2010830 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210832 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110833 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210834
bnc691fda62016-08-12 00:43:1610835 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210836 ASSERT_TRUE(response);
10837 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210838 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10839
10840 std::string response_data;
bnc691fda62016-08-12 00:43:1610841 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210842 EXPECT_EQ("hello world", response_data);
10843}
10844
bncd16676a2016-07-20 16:23:0110845TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410846 HttpRequestInfo request;
10847 request.method = "GET";
bncb26024382016-06-29 02:39:4510848 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410849
10850 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210851 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310852 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210853 MockRead("\r\n"),
10854 MockRead("hello world"),
10855 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10856 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410857
10858 StaticSocketDataProvider first_transaction(
10859 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710860 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510861 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610862 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510863 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410864
bnc032658ba2016-09-26 18:17:1510865 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410866
bncdf80d44fd2016-07-15 20:27:4110867 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510868 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110869 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410870
bnc42331402016-07-25 13:36:1510871 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110872 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410873 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110874 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410875 };
10876
rch8e6c6c42015-05-01 14:05:1310877 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10878 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710879 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410880
[email protected]d973e99a2012-02-17 21:02:3610881 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510882 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10883 NULL, 0, NULL, 0);
10884 hanging_non_alternate_protocol_socket.set_connect_data(
10885 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710886 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510887 &hanging_non_alternate_protocol_socket);
10888
[email protected]49639fa2011-12-20 23:22:4110889 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410890
danakj1fd259a02016-04-16 03:17:0910891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810892 auto trans =
10893 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410894
tfarina42834112016-09-22 13:38:2010895 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10897 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410898
10899 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210900 ASSERT_TRUE(response);
10901 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410902 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10903
10904 std::string response_data;
robpercival214763f2016-07-01 23:27:0110905 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410906 EXPECT_EQ("hello world", response_data);
10907
bnc87dcefc2017-05-25 12:47:5810908 trans =
10909 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410910
tfarina42834112016-09-22 13:38:2010911 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10913 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410914
10915 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210916 ASSERT_TRUE(response);
10917 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210918 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310919 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210920 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410921
robpercival214763f2016-07-01 23:27:0110922 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410923 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410924}
10925
bncd16676a2016-07-20 16:23:0110926TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510927 HttpRequestInfo request;
10928 request.method = "GET";
bncb26024382016-06-29 02:39:4510929 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510930
bncb26024382016-06-29 02:39:4510931 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510932 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210933 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310934 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210935 MockRead("\r\n"),
10936 MockRead("hello world"),
10937 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10938 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510939 };
10940
bncb26024382016-06-29 02:39:4510941 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10942 0);
10943 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510944
bncb26024382016-06-29 02:39:4510945 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10946 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10947
10948 // Second transaction starts an alternative and a non-alternative Job.
10949 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610950 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810951 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10952 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810953 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10954
10955 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10956 hanging_socket2.set_connect_data(never_finishing_connect);
10957 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510958
bncb26024382016-06-29 02:39:4510959 // Third transaction starts an alternative and a non-alternative job.
10960 // The non-alternative job hangs, but the alternative one succeeds.
10961 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110962 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510963 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110964 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510965 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510966 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110967 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510968 };
bnc42331402016-07-25 13:36:1510969 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110970 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510971 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110972 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510973 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110974 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10975 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310976 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510977 };
10978
rch8e6c6c42015-05-01 14:05:1310979 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10980 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710981 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510982
bnc032658ba2016-09-26 18:17:1510983 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510984
mmenkecc2298e2015-12-07 18:20:1810985 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10986 hanging_socket3.set_connect_data(never_finishing_connect);
10987 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510988
danakj1fd259a02016-04-16 03:17:0910989 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110990 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010991 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510992
tfarina42834112016-09-22 13:38:2010993 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10995 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510996
10997 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210998 ASSERT_TRUE(response);
10999 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511000 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11001
11002 std::string response_data;
robpercival214763f2016-07-01 23:27:0111003 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511004 EXPECT_EQ("hello world", response_data);
11005
[email protected]49639fa2011-12-20 23:22:4111006 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011007 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011008 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511010
[email protected]49639fa2011-12-20 23:22:4111011 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011012 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011013 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511015
robpercival214763f2016-07-01 23:27:0111016 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11017 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511018
11019 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211020 ASSERT_TRUE(response);
11021 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211022 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511023 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211024 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111025 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511026 EXPECT_EQ("hello!", response_data);
11027
11028 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211029 ASSERT_TRUE(response);
11030 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211031 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511032 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211033 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111034 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511035 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511036}
11037
bncd16676a2016-07-20 16:23:0111038TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511039 HttpRequestInfo request;
11040 request.method = "GET";
bncb26024382016-06-29 02:39:4511041 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511042
11043 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211044 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311045 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211046 MockRead("\r\n"),
11047 MockRead("hello world"),
11048 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11049 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511050 };
11051
11052 StaticSocketDataProvider first_transaction(
11053 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711054 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511055
[email protected]8ddf8322012-02-23 18:08:0611056 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511058
[email protected]d973e99a2012-02-17 21:02:3611059 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511060 StaticSocketDataProvider hanging_alternate_protocol_socket(
11061 NULL, 0, NULL, 0);
11062 hanging_alternate_protocol_socket.set_connect_data(
11063 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711064 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511065 &hanging_alternate_protocol_socket);
11066
bncb26024382016-06-29 02:39:4511067 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811068 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11069 NULL, 0);
11070 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511072
[email protected]49639fa2011-12-20 23:22:4111073 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511074
danakj1fd259a02016-04-16 03:17:0911075 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811076 auto trans =
11077 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511078
tfarina42834112016-09-22 13:38:2011079 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11081 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511082
11083 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211084 ASSERT_TRUE(response);
11085 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511086 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11087
11088 std::string response_data;
robpercival214763f2016-07-01 23:27:0111089 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511090 EXPECT_EQ("hello world", response_data);
11091
bnc87dcefc2017-05-25 12:47:5811092 trans =
11093 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511094
tfarina42834112016-09-22 13:38:2011095 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11097 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511098
11099 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211100 ASSERT_TRUE(response);
11101 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511102 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11103 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211104 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511105
robpercival214763f2016-07-01 23:27:0111106 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511107 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511108}
11109
[email protected]631f1322010-04-30 17:59:1111110class CapturingProxyResolver : public ProxyResolver {
11111 public:
sammce90c9212015-05-27 23:43:3511112 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011113 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111114
dchengb03027d2014-10-21 12:00:2011115 int GetProxyForURL(const GURL& url,
11116 ProxyInfo* results,
11117 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511118 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011119 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011120 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11121 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211122 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111123 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211124 return OK;
[email protected]631f1322010-04-30 17:59:1111125 }
11126
[email protected]24476402010-07-20 20:55:1711127 const std::vector<GURL>& resolved() const { return resolved_; }
11128
11129 private:
[email protected]631f1322010-04-30 17:59:1111130 std::vector<GURL> resolved_;
11131
11132 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11133};
11134
sammce64b2362015-04-29 03:50:2311135class CapturingProxyResolverFactory : public ProxyResolverFactory {
11136 public:
11137 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11138 : ProxyResolverFactory(false), resolver_(resolver) {}
11139
11140 int CreateProxyResolver(
11141 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911142 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311143 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911144 std::unique_ptr<Request>* request) override {
bnc87dcefc2017-05-25 12:47:5811145 *resolver = base::MakeUnique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311146 return OK;
11147 }
11148
11149 private:
11150 ProxyResolver* resolver_;
11151};
11152
bnc2e884782016-08-11 19:45:1911153// Test that proxy is resolved using the origin url,
11154// regardless of the alternative server.
11155TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11156 // Configure proxy to bypass www.example.org, which is the origin URL.
11157 ProxyConfig proxy_config;
11158 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11159 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11160 auto proxy_config_service =
11161 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11162
11163 CapturingProxyResolver capturing_proxy_resolver;
11164 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11165 &capturing_proxy_resolver);
11166
11167 TestNetLog net_log;
11168
11169 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11170 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11171 &net_log);
11172
11173 session_deps_.net_log = &net_log;
11174
11175 // Configure alternative service with a hostname that is not bypassed by the
11176 // proxy.
11177 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11178 HttpServerProperties* http_server_properties =
11179 session->http_server_properties();
11180 url::SchemeHostPort server("https", "www.example.org", 443);
11181 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111182 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911183 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11184 http_server_properties->SetAlternativeService(server, alternative_service,
11185 expiration);
11186
11187 // Non-alternative job should hang.
11188 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11189 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11190 nullptr, 0);
11191 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11192 session_deps_.socket_factory->AddSocketDataProvider(
11193 &hanging_alternate_protocol_socket);
11194
bnc032658ba2016-09-26 18:17:1511195 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911196
11197 HttpRequestInfo request;
11198 request.method = "GET";
11199 request.url = GURL("https://www.example.org/");
11200 request.load_flags = 0;
11201
11202 SpdySerializedFrame req(
11203 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11204
11205 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11206
11207 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11208 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11209 MockRead spdy_reads[] = {
11210 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11211 };
11212
11213 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11214 arraysize(spdy_writes));
11215 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11216
11217 TestCompletionCallback callback;
11218
11219 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11220
tfarina42834112016-09-22 13:38:2011221 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911222 EXPECT_THAT(callback.GetResult(rv), IsOk());
11223
11224 const HttpResponseInfo* response = trans.GetResponseInfo();
11225 ASSERT_TRUE(response);
11226 ASSERT_TRUE(response->headers);
11227 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11228 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211229 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911230
11231 std::string response_data;
11232 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11233 EXPECT_EQ("hello!", response_data);
11234
11235 // Origin host bypasses proxy, no resolution should have happened.
11236 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11237}
11238
bncd16676a2016-07-20 16:23:0111239TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111240 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211241 proxy_config.set_auto_detect(true);
11242 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111243
sammc5dd160c2015-04-02 02:43:1311244 CapturingProxyResolver capturing_proxy_resolver;
bnc87dcefc2017-05-25 12:47:5811245 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11246 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11247 base::MakeUnique<CapturingProxyResolverFactory>(
11248 &capturing_proxy_resolver),
11249 nullptr);
vishal.b62985ca92015-04-17 08:45:5111250 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711251 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111252
11253 HttpRequestInfo request;
11254 request.method = "GET";
bncb26024382016-06-29 02:39:4511255 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111256
11257 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211258 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311259 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211260 MockRead("\r\n"),
11261 MockRead("hello world"),
11262 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11263 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111264 };
11265
11266 StaticSocketDataProvider first_transaction(
11267 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711268 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511269 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611270 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111272
bnc032658ba2016-09-26 18:17:1511273 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111274
bncdf80d44fd2016-07-15 20:27:4111275 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511276 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111277 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311278 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511279 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11280 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311281 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111282 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111283 };
11284
[email protected]d911f1b2010-05-05 22:39:4211285 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11286
bnc42331402016-07-25 13:36:1511287 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111288 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111289 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111290 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11291 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111292 };
11293
rch8e6c6c42015-05-01 14:05:1311294 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11295 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711296 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111297
[email protected]d973e99a2012-02-17 21:02:3611298 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511299 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11300 NULL, 0, NULL, 0);
11301 hanging_non_alternate_protocol_socket.set_connect_data(
11302 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711303 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511304 &hanging_non_alternate_protocol_socket);
11305
[email protected]49639fa2011-12-20 23:22:4111306 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111307
danakj1fd259a02016-04-16 03:17:0911308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811309 auto trans =
11310 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111311
tfarina42834112016-09-22 13:38:2011312 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111313 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11314 EXPECT_THAT(callback.WaitForResult(), IsOk());
11315
11316 const HttpResponseInfo* response = trans->GetResponseInfo();
11317 ASSERT_TRUE(response);
11318 ASSERT_TRUE(response->headers);
11319 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11320 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211321 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111322
11323 std::string response_data;
11324 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11325 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111326
bnc87dcefc2017-05-25 12:47:5811327 trans =
11328 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111329
tfarina42834112016-09-22 13:38:2011330 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111331 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11332 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111333
mmenkea2dcd3bf2016-08-16 21:49:4111334 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211335 ASSERT_TRUE(response);
11336 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211337 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311338 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211339 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111340
robpercival214763f2016-07-01 23:27:0111341 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111342 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511343 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11344 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311345 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311346 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311347 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111348
[email protected]029c83b62013-01-24 05:28:2011349 LoadTimingInfo load_timing_info;
11350 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11351 TestLoadTimingNotReusedWithPac(load_timing_info,
11352 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111353}
[email protected]631f1322010-04-30 17:59:1111354
bncd16676a2016-07-20 16:23:0111355TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811356 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411357 HttpRequestInfo request;
11358 request.method = "GET";
bncb26024382016-06-29 02:39:4511359 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411360
11361 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211362 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311363 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211364 MockRead("\r\n"),
11365 MockRead("hello world"),
11366 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411367 };
11368
11369 StaticSocketDataProvider first_transaction(
11370 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711371 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511372 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611373 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411375
bnc032658ba2016-09-26 18:17:1511376 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411377
bncdf80d44fd2016-07-15 20:27:4111378 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511379 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111380 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411381
bnc42331402016-07-25 13:36:1511382 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111383 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411384 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111385 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411386 };
11387
rch8e6c6c42015-05-01 14:05:1311388 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11389 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711390 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411391
[email protected]83039bb2011-12-09 18:43:5511392 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411393
danakj1fd259a02016-04-16 03:17:0911394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411395
bnc87dcefc2017-05-25 12:47:5811396 auto trans =
11397 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411398
tfarina42834112016-09-22 13:38:2011399 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11401 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411402
11403 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211404 ASSERT_TRUE(response);
11405 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411406 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11407
11408 std::string response_data;
robpercival214763f2016-07-01 23:27:0111409 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411410 EXPECT_EQ("hello world", response_data);
11411
11412 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511413 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011414 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311415 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711416 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011417 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811418
bnc87dcefc2017-05-25 12:47:5811419 trans =
11420 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411421
tfarina42834112016-09-22 13:38:2011422 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111423 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11424 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411425
11426 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211427 ASSERT_TRUE(response);
11428 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211429 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311430 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211431 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411432
robpercival214763f2016-07-01 23:27:0111433 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411434 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211435}
11436
[email protected]044de0642010-06-17 10:42:1511437// GenerateAuthToken is a mighty big test.
11438// It tests all permutation of GenerateAuthToken behavior:
11439// - Synchronous and Asynchronous completion.
11440// - OK or error on completion.
11441// - Direct connection, non-authenticating proxy, and authenticating proxy.
11442// - HTTP or HTTPS backend (to include proxy tunneling).
11443// - Non-authenticating and authenticating backend.
11444//
[email protected]fe3b7dc2012-02-03 19:52:0911445// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511446// problems generating an auth token for an authenticating proxy, we don't
11447// need to test all permutations of the backend server).
11448//
11449// The test proceeds by going over each of the configuration cases, and
11450// potentially running up to three rounds in each of the tests. The TestConfig
11451// specifies both the configuration for the test as well as the expectations
11452// for the results.
bncd16676a2016-07-20 16:23:0111453TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011454 static const char kServer[] = "http://www.example.com";
11455 static const char kSecureServer[] = "https://www.example.com";
11456 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511457
11458 enum AuthTiming {
11459 AUTH_NONE,
11460 AUTH_SYNC,
11461 AUTH_ASYNC,
11462 };
11463
11464 const MockWrite kGet(
11465 "GET / HTTP/1.1\r\n"
11466 "Host: www.example.com\r\n"
11467 "Connection: keep-alive\r\n\r\n");
11468 const MockWrite kGetProxy(
11469 "GET http://www.example.com/ HTTP/1.1\r\n"
11470 "Host: www.example.com\r\n"
11471 "Proxy-Connection: keep-alive\r\n\r\n");
11472 const MockWrite kGetAuth(
11473 "GET / HTTP/1.1\r\n"
11474 "Host: www.example.com\r\n"
11475 "Connection: keep-alive\r\n"
11476 "Authorization: auth_token\r\n\r\n");
11477 const MockWrite kGetProxyAuth(
11478 "GET http://www.example.com/ HTTP/1.1\r\n"
11479 "Host: www.example.com\r\n"
11480 "Proxy-Connection: keep-alive\r\n"
11481 "Proxy-Authorization: auth_token\r\n\r\n");
11482 const MockWrite kGetAuthThroughProxy(
11483 "GET http://www.example.com/ HTTP/1.1\r\n"
11484 "Host: www.example.com\r\n"
11485 "Proxy-Connection: keep-alive\r\n"
11486 "Authorization: auth_token\r\n\r\n");
11487 const MockWrite kGetAuthWithProxyAuth(
11488 "GET http://www.example.com/ HTTP/1.1\r\n"
11489 "Host: www.example.com\r\n"
11490 "Proxy-Connection: keep-alive\r\n"
11491 "Proxy-Authorization: auth_token\r\n"
11492 "Authorization: auth_token\r\n\r\n");
11493 const MockWrite kConnect(
11494 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711495 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511496 "Proxy-Connection: keep-alive\r\n\r\n");
11497 const MockWrite kConnectProxyAuth(
11498 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711499 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511500 "Proxy-Connection: keep-alive\r\n"
11501 "Proxy-Authorization: auth_token\r\n\r\n");
11502
11503 const MockRead kSuccess(
11504 "HTTP/1.1 200 OK\r\n"
11505 "Content-Type: text/html; charset=iso-8859-1\r\n"
11506 "Content-Length: 3\r\n\r\n"
11507 "Yes");
11508 const MockRead kFailure(
11509 "Should not be called.");
11510 const MockRead kServerChallenge(
11511 "HTTP/1.1 401 Unauthorized\r\n"
11512 "WWW-Authenticate: Mock realm=server\r\n"
11513 "Content-Type: text/html; charset=iso-8859-1\r\n"
11514 "Content-Length: 14\r\n\r\n"
11515 "Unauthorized\r\n");
11516 const MockRead kProxyChallenge(
11517 "HTTP/1.1 407 Unauthorized\r\n"
11518 "Proxy-Authenticate: Mock realm=proxy\r\n"
11519 "Proxy-Connection: close\r\n"
11520 "Content-Type: text/html; charset=iso-8859-1\r\n"
11521 "Content-Length: 14\r\n\r\n"
11522 "Unauthorized\r\n");
11523 const MockRead kProxyConnected(
11524 "HTTP/1.1 200 Connection Established\r\n\r\n");
11525
11526 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11527 // no constructors, but the C++ compiler on Windows warns about
11528 // unspecified data in compound literals. So, moved to using constructors,
11529 // and TestRound's created with the default constructor should not be used.
11530 struct TestRound {
11531 TestRound()
11532 : expected_rv(ERR_UNEXPECTED),
11533 extra_write(NULL),
11534 extra_read(NULL) {
11535 }
11536 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11537 int expected_rv_arg)
11538 : write(write_arg),
11539 read(read_arg),
11540 expected_rv(expected_rv_arg),
11541 extra_write(NULL),
11542 extra_read(NULL) {
11543 }
11544 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11545 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111546 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511547 : write(write_arg),
11548 read(read_arg),
11549 expected_rv(expected_rv_arg),
11550 extra_write(extra_write_arg),
11551 extra_read(extra_read_arg) {
11552 }
11553 MockWrite write;
11554 MockRead read;
11555 int expected_rv;
11556 const MockWrite* extra_write;
11557 const MockRead* extra_read;
11558 };
11559
11560 static const int kNoSSL = 500;
11561
11562 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111563 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111564 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511565 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111566 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111567 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511568 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111569 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511570 int num_auth_rounds;
11571 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611572 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511573 } test_configs[] = {
asankac93076192016-10-03 15:46:0211574 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111575 {__LINE__,
11576 nullptr,
asankac93076192016-10-03 15:46:0211577 AUTH_NONE,
11578 OK,
11579 kServer,
11580 AUTH_NONE,
11581 OK,
11582 1,
11583 kNoSSL,
11584 {TestRound(kGet, kSuccess, OK)}},
11585 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111586 {__LINE__,
11587 nullptr,
asankac93076192016-10-03 15:46:0211588 AUTH_NONE,
11589 OK,
11590 kServer,
11591 AUTH_SYNC,
11592 OK,
11593 2,
11594 kNoSSL,
11595 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511596 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111597 {__LINE__,
11598 nullptr,
asankac93076192016-10-03 15:46:0211599 AUTH_NONE,
11600 OK,
11601 kServer,
11602 AUTH_SYNC,
11603 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611604 3,
11605 kNoSSL,
11606 {TestRound(kGet, kServerChallenge, OK),
11607 TestRound(kGet, kServerChallenge, OK),
11608 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111609 {__LINE__,
11610 nullptr,
asankae2257db2016-10-11 22:03:1611611 AUTH_NONE,
11612 OK,
11613 kServer,
11614 AUTH_SYNC,
11615 ERR_UNSUPPORTED_AUTH_SCHEME,
11616 2,
11617 kNoSSL,
11618 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111619 {__LINE__,
11620 nullptr,
asankae2257db2016-10-11 22:03:1611621 AUTH_NONE,
11622 OK,
11623 kServer,
11624 AUTH_SYNC,
11625 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11626 2,
11627 kNoSSL,
11628 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111629 {__LINE__,
11630 kProxy,
asankae2257db2016-10-11 22:03:1611631 AUTH_SYNC,
11632 ERR_FAILED,
11633 kServer,
11634 AUTH_NONE,
11635 OK,
11636 2,
11637 kNoSSL,
11638 {TestRound(kGetProxy, kProxyChallenge, OK),
11639 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111640 {__LINE__,
11641 kProxy,
asankae2257db2016-10-11 22:03:1611642 AUTH_ASYNC,
11643 ERR_FAILED,
11644 kServer,
11645 AUTH_NONE,
11646 OK,
11647 2,
11648 kNoSSL,
11649 {TestRound(kGetProxy, kProxyChallenge, OK),
11650 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111651 {__LINE__,
11652 nullptr,
asankae2257db2016-10-11 22:03:1611653 AUTH_NONE,
11654 OK,
11655 kServer,
11656 AUTH_SYNC,
11657 ERR_FAILED,
asankac93076192016-10-03 15:46:0211658 2,
11659 kNoSSL,
11660 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611661 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111662 {__LINE__,
11663 nullptr,
asankae2257db2016-10-11 22:03:1611664 AUTH_NONE,
11665 OK,
11666 kServer,
11667 AUTH_ASYNC,
11668 ERR_FAILED,
11669 2,
11670 kNoSSL,
11671 {TestRound(kGet, kServerChallenge, OK),
11672 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111673 {__LINE__,
11674 nullptr,
asankac93076192016-10-03 15:46:0211675 AUTH_NONE,
11676 OK,
11677 kServer,
11678 AUTH_ASYNC,
11679 OK,
11680 2,
11681 kNoSSL,
11682 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511683 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111684 {__LINE__,
11685 nullptr,
asankac93076192016-10-03 15:46:0211686 AUTH_NONE,
11687 OK,
11688 kServer,
11689 AUTH_ASYNC,
11690 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611691 3,
asankac93076192016-10-03 15:46:0211692 kNoSSL,
11693 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611694 // The second round uses a HttpAuthHandlerMock that always succeeds.
11695 TestRound(kGet, kServerChallenge, OK),
11696 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211697 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111698 {__LINE__,
11699 kProxy,
asankac93076192016-10-03 15:46:0211700 AUTH_NONE,
11701 OK,
11702 kServer,
11703 AUTH_NONE,
11704 OK,
11705 1,
11706 kNoSSL,
11707 {TestRound(kGetProxy, kSuccess, OK)}},
11708 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111709 {__LINE__,
11710 kProxy,
asankac93076192016-10-03 15:46:0211711 AUTH_NONE,
11712 OK,
11713 kServer,
11714 AUTH_SYNC,
11715 OK,
11716 2,
11717 kNoSSL,
11718 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511719 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111720 {__LINE__,
11721 kProxy,
asankac93076192016-10-03 15:46:0211722 AUTH_NONE,
11723 OK,
11724 kServer,
11725 AUTH_SYNC,
11726 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611727 3,
asankac93076192016-10-03 15:46:0211728 kNoSSL,
11729 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611730 TestRound(kGetProxy, kServerChallenge, OK),
11731 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111732 {__LINE__,
11733 kProxy,
asankac93076192016-10-03 15:46:0211734 AUTH_NONE,
11735 OK,
11736 kServer,
11737 AUTH_ASYNC,
11738 OK,
11739 2,
11740 kNoSSL,
11741 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511742 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111743 {__LINE__,
11744 kProxy,
asankac93076192016-10-03 15:46:0211745 AUTH_NONE,
11746 OK,
11747 kServer,
11748 AUTH_ASYNC,
11749 ERR_INVALID_AUTH_CREDENTIALS,
11750 2,
11751 kNoSSL,
11752 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611753 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211754 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111755 {__LINE__,
11756 kProxy,
asankac93076192016-10-03 15:46:0211757 AUTH_SYNC,
11758 OK,
11759 kServer,
11760 AUTH_NONE,
11761 OK,
11762 2,
11763 kNoSSL,
11764 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511765 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111766 {__LINE__,
11767 kProxy,
asankac93076192016-10-03 15:46:0211768 AUTH_SYNC,
11769 ERR_INVALID_AUTH_CREDENTIALS,
11770 kServer,
11771 AUTH_NONE,
11772 OK,
11773 2,
11774 kNoSSL,
11775 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611776 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111777 {__LINE__,
11778 kProxy,
asankac93076192016-10-03 15:46:0211779 AUTH_ASYNC,
11780 OK,
11781 kServer,
11782 AUTH_NONE,
11783 OK,
11784 2,
11785 kNoSSL,
11786 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511787 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111788 {__LINE__,
11789 kProxy,
asankac93076192016-10-03 15:46:0211790 AUTH_ASYNC,
11791 ERR_INVALID_AUTH_CREDENTIALS,
11792 kServer,
11793 AUTH_NONE,
11794 OK,
11795 2,
11796 kNoSSL,
11797 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611798 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111799 {__LINE__,
11800 kProxy,
11801 AUTH_ASYNC,
11802 ERR_INVALID_AUTH_CREDENTIALS,
11803 kServer,
11804 AUTH_NONE,
11805 OK,
11806 3,
11807 kNoSSL,
11808 {TestRound(kGetProxy, kProxyChallenge, OK),
11809 TestRound(kGetProxy, kProxyChallenge, OK),
11810 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211811 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111812 {__LINE__,
11813 kProxy,
asankac93076192016-10-03 15:46:0211814 AUTH_SYNC,
11815 OK,
11816 kServer,
11817 AUTH_SYNC,
11818 OK,
11819 3,
11820 kNoSSL,
11821 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511822 TestRound(kGetProxyAuth, kServerChallenge, OK),
11823 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111824 {__LINE__,
11825 kProxy,
asankac93076192016-10-03 15:46:0211826 AUTH_SYNC,
11827 OK,
11828 kServer,
11829 AUTH_SYNC,
11830 ERR_INVALID_AUTH_CREDENTIALS,
11831 3,
11832 kNoSSL,
11833 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511834 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611835 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111836 {__LINE__,
11837 kProxy,
asankac93076192016-10-03 15:46:0211838 AUTH_ASYNC,
11839 OK,
11840 kServer,
11841 AUTH_SYNC,
11842 OK,
11843 3,
11844 kNoSSL,
11845 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511846 TestRound(kGetProxyAuth, kServerChallenge, OK),
11847 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111848 {__LINE__,
11849 kProxy,
asankac93076192016-10-03 15:46:0211850 AUTH_ASYNC,
11851 OK,
11852 kServer,
11853 AUTH_SYNC,
11854 ERR_INVALID_AUTH_CREDENTIALS,
11855 3,
11856 kNoSSL,
11857 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511858 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611859 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111860 {__LINE__,
11861 kProxy,
asankac93076192016-10-03 15:46:0211862 AUTH_SYNC,
11863 OK,
11864 kServer,
11865 AUTH_ASYNC,
11866 OK,
11867 3,
11868 kNoSSL,
11869 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511870 TestRound(kGetProxyAuth, kServerChallenge, OK),
11871 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111872 {__LINE__,
11873 kProxy,
11874 AUTH_SYNC,
11875 ERR_INVALID_AUTH_CREDENTIALS,
11876 kServer,
11877 AUTH_ASYNC,
11878 OK,
11879 4,
11880 kNoSSL,
11881 {TestRound(kGetProxy, kProxyChallenge, OK),
11882 TestRound(kGetProxy, kProxyChallenge, OK),
11883 TestRound(kGetProxyAuth, kServerChallenge, OK),
11884 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11885 {__LINE__,
11886 kProxy,
asankac93076192016-10-03 15:46:0211887 AUTH_SYNC,
11888 OK,
11889 kServer,
11890 AUTH_ASYNC,
11891 ERR_INVALID_AUTH_CREDENTIALS,
11892 3,
11893 kNoSSL,
11894 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511895 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611896 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111897 {__LINE__,
11898 kProxy,
asankac93076192016-10-03 15:46:0211899 AUTH_ASYNC,
11900 OK,
11901 kServer,
11902 AUTH_ASYNC,
11903 OK,
11904 3,
11905 kNoSSL,
11906 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511907 TestRound(kGetProxyAuth, kServerChallenge, OK),
11908 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111909 {__LINE__,
11910 kProxy,
asankac93076192016-10-03 15:46:0211911 AUTH_ASYNC,
11912 OK,
11913 kServer,
11914 AUTH_ASYNC,
11915 ERR_INVALID_AUTH_CREDENTIALS,
11916 3,
11917 kNoSSL,
11918 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511919 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611920 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111921 {__LINE__,
11922 kProxy,
11923 AUTH_ASYNC,
11924 ERR_INVALID_AUTH_CREDENTIALS,
11925 kServer,
11926 AUTH_ASYNC,
11927 ERR_INVALID_AUTH_CREDENTIALS,
11928 4,
11929 kNoSSL,
11930 {TestRound(kGetProxy, kProxyChallenge, OK),
11931 TestRound(kGetProxy, kProxyChallenge, OK),
11932 TestRound(kGetProxyAuth, kServerChallenge, OK),
11933 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211934 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111935 {__LINE__,
11936 nullptr,
asankac93076192016-10-03 15:46:0211937 AUTH_NONE,
11938 OK,
11939 kSecureServer,
11940 AUTH_NONE,
11941 OK,
11942 1,
11943 0,
11944 {TestRound(kGet, kSuccess, OK)}},
11945 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111946 {__LINE__,
11947 nullptr,
asankac93076192016-10-03 15:46:0211948 AUTH_NONE,
11949 OK,
11950 kSecureServer,
11951 AUTH_SYNC,
11952 OK,
11953 2,
11954 0,
11955 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511956 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111957 {__LINE__,
11958 nullptr,
asankac93076192016-10-03 15:46:0211959 AUTH_NONE,
11960 OK,
11961 kSecureServer,
11962 AUTH_SYNC,
11963 ERR_INVALID_AUTH_CREDENTIALS,
11964 2,
11965 0,
asankae2257db2016-10-11 22:03:1611966 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111967 {__LINE__,
11968 nullptr,
asankac93076192016-10-03 15:46:0211969 AUTH_NONE,
11970 OK,
11971 kSecureServer,
11972 AUTH_ASYNC,
11973 OK,
11974 2,
11975 0,
11976 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511977 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111978 {__LINE__,
11979 nullptr,
asankac93076192016-10-03 15:46:0211980 AUTH_NONE,
11981 OK,
11982 kSecureServer,
11983 AUTH_ASYNC,
11984 ERR_INVALID_AUTH_CREDENTIALS,
11985 2,
11986 0,
asankae2257db2016-10-11 22:03:1611987 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211988 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111989 {__LINE__,
11990 kProxy,
asankac93076192016-10-03 15:46:0211991 AUTH_NONE,
11992 OK,
11993 kSecureServer,
11994 AUTH_NONE,
11995 OK,
11996 1,
11997 0,
11998 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11999 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112000 {__LINE__,
12001 kProxy,
asankac93076192016-10-03 15:46:0212002 AUTH_NONE,
12003 OK,
12004 kSecureServer,
12005 AUTH_SYNC,
12006 OK,
12007 2,
12008 0,
12009 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512010 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112011 {__LINE__,
12012 kProxy,
asankac93076192016-10-03 15:46:0212013 AUTH_NONE,
12014 OK,
12015 kSecureServer,
12016 AUTH_SYNC,
12017 ERR_INVALID_AUTH_CREDENTIALS,
12018 2,
12019 0,
12020 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612021 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112022 {__LINE__,
12023 kProxy,
asankac93076192016-10-03 15:46:0212024 AUTH_NONE,
12025 OK,
12026 kSecureServer,
12027 AUTH_ASYNC,
12028 OK,
12029 2,
12030 0,
12031 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512032 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112033 {__LINE__,
12034 kProxy,
asankac93076192016-10-03 15:46:0212035 AUTH_NONE,
12036 OK,
12037 kSecureServer,
12038 AUTH_ASYNC,
12039 ERR_INVALID_AUTH_CREDENTIALS,
12040 2,
12041 0,
12042 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612043 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212044 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112045 {__LINE__,
12046 kProxy,
asankac93076192016-10-03 15:46:0212047 AUTH_SYNC,
12048 OK,
12049 kSecureServer,
12050 AUTH_NONE,
12051 OK,
12052 2,
12053 1,
12054 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512055 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112056 {__LINE__,
12057 kProxy,
asankac93076192016-10-03 15:46:0212058 AUTH_SYNC,
12059 ERR_INVALID_AUTH_CREDENTIALS,
12060 kSecureServer,
12061 AUTH_NONE,
12062 OK,
12063 2,
12064 kNoSSL,
12065 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612066 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112067 {__LINE__,
12068 kProxy,
asankae2257db2016-10-11 22:03:1612069 AUTH_SYNC,
12070 ERR_UNSUPPORTED_AUTH_SCHEME,
12071 kSecureServer,
12072 AUTH_NONE,
12073 OK,
12074 2,
12075 kNoSSL,
12076 {TestRound(kConnect, kProxyChallenge, OK),
12077 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112078 {__LINE__,
12079 kProxy,
asankae2257db2016-10-11 22:03:1612080 AUTH_SYNC,
12081 ERR_UNEXPECTED,
12082 kSecureServer,
12083 AUTH_NONE,
12084 OK,
12085 2,
12086 kNoSSL,
12087 {TestRound(kConnect, kProxyChallenge, OK),
12088 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112089 {__LINE__,
12090 kProxy,
asankac93076192016-10-03 15:46:0212091 AUTH_ASYNC,
12092 OK,
12093 kSecureServer,
12094 AUTH_NONE,
12095 OK,
12096 2,
12097 1,
12098 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512099 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112100 {__LINE__,
12101 kProxy,
asankac93076192016-10-03 15:46:0212102 AUTH_ASYNC,
12103 ERR_INVALID_AUTH_CREDENTIALS,
12104 kSecureServer,
12105 AUTH_NONE,
12106 OK,
12107 2,
12108 kNoSSL,
12109 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612110 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212111 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112112 {__LINE__,
12113 kProxy,
asankac93076192016-10-03 15:46:0212114 AUTH_SYNC,
12115 OK,
12116 kSecureServer,
12117 AUTH_SYNC,
12118 OK,
12119 3,
12120 1,
12121 {TestRound(kConnect, kProxyChallenge, OK),
12122 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12123 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512124 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112125 {__LINE__,
12126 kProxy,
asankac93076192016-10-03 15:46:0212127 AUTH_SYNC,
12128 OK,
12129 kSecureServer,
12130 AUTH_SYNC,
12131 ERR_INVALID_AUTH_CREDENTIALS,
12132 3,
12133 1,
12134 {TestRound(kConnect, kProxyChallenge, OK),
12135 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12136 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612137 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112138 {__LINE__,
12139 kProxy,
asankac93076192016-10-03 15:46:0212140 AUTH_ASYNC,
12141 OK,
12142 kSecureServer,
12143 AUTH_SYNC,
12144 OK,
12145 3,
12146 1,
12147 {TestRound(kConnect, kProxyChallenge, OK),
12148 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12149 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512150 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112151 {__LINE__,
12152 kProxy,
asankac93076192016-10-03 15:46:0212153 AUTH_ASYNC,
12154 OK,
12155 kSecureServer,
12156 AUTH_SYNC,
12157 ERR_INVALID_AUTH_CREDENTIALS,
12158 3,
12159 1,
12160 {TestRound(kConnect, kProxyChallenge, OK),
12161 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12162 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612163 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112164 {__LINE__,
12165 kProxy,
asankac93076192016-10-03 15:46:0212166 AUTH_SYNC,
12167 OK,
12168 kSecureServer,
12169 AUTH_ASYNC,
12170 OK,
12171 3,
12172 1,
12173 {TestRound(kConnect, kProxyChallenge, OK),
12174 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12175 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512176 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112177 {__LINE__,
12178 kProxy,
asankac93076192016-10-03 15:46:0212179 AUTH_SYNC,
12180 OK,
12181 kSecureServer,
12182 AUTH_ASYNC,
12183 ERR_INVALID_AUTH_CREDENTIALS,
12184 3,
12185 1,
12186 {TestRound(kConnect, kProxyChallenge, OK),
12187 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12188 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612189 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112190 {__LINE__,
12191 kProxy,
asankac93076192016-10-03 15:46:0212192 AUTH_ASYNC,
12193 OK,
12194 kSecureServer,
12195 AUTH_ASYNC,
12196 OK,
12197 3,
12198 1,
12199 {TestRound(kConnect, kProxyChallenge, OK),
12200 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12201 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512202 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112203 {__LINE__,
12204 kProxy,
asankac93076192016-10-03 15:46:0212205 AUTH_ASYNC,
12206 OK,
12207 kSecureServer,
12208 AUTH_ASYNC,
12209 ERR_INVALID_AUTH_CREDENTIALS,
12210 3,
12211 1,
12212 {TestRound(kConnect, kProxyChallenge, OK),
12213 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12214 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612215 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112216 {__LINE__,
12217 kProxy,
12218 AUTH_ASYNC,
12219 ERR_INVALID_AUTH_CREDENTIALS,
12220 kSecureServer,
12221 AUTH_ASYNC,
12222 ERR_INVALID_AUTH_CREDENTIALS,
12223 4,
12224 2,
12225 {TestRound(kConnect, kProxyChallenge, OK),
12226 TestRound(kConnect, kProxyChallenge, OK),
12227 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12228 &kServerChallenge),
12229 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512230 };
12231
asanka463ca4262016-11-16 02:34:3112232 for (const auto& test_config : test_configs) {
12233 SCOPED_TRACE(::testing::Message() << "Test config at "
12234 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812235 HttpAuthHandlerMock::Factory* auth_factory(
12236 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712237 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912238 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612239
12240 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512241 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112242 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812243 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12244 std::string auth_challenge = "Mock realm=proxy";
12245 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412246 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12247 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812248 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012249 empty_ssl_info, origin,
12250 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812251 auth_handler->SetGenerateExpectation(
12252 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112253 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812254 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12255 }
[email protected]044de0642010-06-17 10:42:1512256 }
12257 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012258 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512259 std::string auth_challenge = "Mock realm=server";
12260 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412261 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12262 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512263 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012264 empty_ssl_info, origin,
12265 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512266 auth_handler->SetGenerateExpectation(
12267 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112268 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812269 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612270
12271 // The second handler always succeeds. It should only be used where there
12272 // are multiple auth sessions for server auth in the same network
12273 // transaction using the same auth scheme.
12274 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12275 base::MakeUnique<HttpAuthHandlerMock>();
12276 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12277 empty_ssl_info, origin,
12278 NetLogWithSource());
12279 second_handler->SetGenerateExpectation(true, OK);
12280 auth_factory->AddMockHandler(second_handler.release(),
12281 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512282 }
12283 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312284 session_deps_.proxy_service =
12285 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512286 } else {
rdsmith82957ad2015-09-16 19:42:0312287 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512288 }
12289
12290 HttpRequestInfo request;
12291 request.method = "GET";
12292 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512293
danakj1fd259a02016-04-16 03:17:0912294 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512295
rchcb68dc62015-05-21 04:45:3612296 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12297
12298 std::vector<std::vector<MockRead>> mock_reads(1);
12299 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512300 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212301 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512302 const TestRound& read_write_round = test_config.rounds[round];
12303
12304 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612305 mock_reads.back().push_back(read_write_round.read);
12306 mock_writes.back().push_back(read_write_round.write);
12307
12308 // kProxyChallenge uses Proxy-Connection: close which means that the
12309 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412310 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612311 mock_reads.push_back(std::vector<MockRead>());
12312 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512313 }
12314
rchcb68dc62015-05-21 04:45:3612315 if (read_write_round.extra_read) {
12316 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512317 }
rchcb68dc62015-05-21 04:45:3612318 if (read_write_round.extra_write) {
12319 mock_writes.back().push_back(*read_write_round.extra_write);
12320 }
[email protected]044de0642010-06-17 10:42:1512321
12322 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512323 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712324 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512325 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612326 }
[email protected]044de0642010-06-17 10:42:1512327
danakj1fd259a02016-04-16 03:17:0912328 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612329 for (size_t i = 0; i < mock_reads.size(); ++i) {
bnc87dcefc2017-05-25 12:47:5812330 data_providers.push_back(base::MakeUnique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412331 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812332 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612333 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212334 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612335 }
12336
mmenkecc2298e2015-12-07 18:20:1812337 // Transaction must be created after DataProviders, so it's destroyed before
12338 // they are as well.
12339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12340
rchcb68dc62015-05-21 04:45:3612341 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212342 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612343 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512344 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112345 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512346 int rv;
12347 if (round == 0) {
tfarina42834112016-09-22 13:38:2012348 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512349 } else {
[email protected]49639fa2011-12-20 23:22:4112350 rv = trans.RestartWithAuth(
12351 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512352 }
12353 if (rv == ERR_IO_PENDING)
12354 rv = callback.WaitForResult();
12355
12356 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612357 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012358 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512359 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512360 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12361 continue;
12362 }
12363 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212364 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512365 } else {
wezca1070932016-05-26 20:30:5212366 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612367 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512368 }
12369 }
[email protected]e5ae96a2010-04-14 20:12:4512370 }
12371}
12372
bncd16676a2016-07-20 16:23:0112373TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412374 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412375 HttpAuthHandlerMock::Factory* auth_factory(
12376 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712377 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312378 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712379 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12380 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412381
12382 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12383 auth_handler->set_connection_based(true);
12384 std::string auth_challenge = "Mock realm=server";
12385 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412386 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12387 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912388 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412389 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012390 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812391 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412392
[email protected]c871bce92010-07-15 21:51:1412393 int rv = OK;
12394 const HttpResponseInfo* response = NULL;
12395 HttpRequestInfo request;
12396 request.method = "GET";
12397 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712398
danakj1fd259a02016-04-16 03:17:0912399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012400
12401 // Use a TCP Socket Pool with only one connection per group. This is used
12402 // to validate that the TCP socket is not released to the pool between
12403 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212404 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812405 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012406 50, // Max sockets for pool
12407 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112408 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12409 NULL, session_deps_.net_log);
bnc87dcefc2017-05-25 12:47:5812410 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212411 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812412 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012413
bnc691fda62016-08-12 00:43:1612414 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112415 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412416
12417 const MockWrite kGet(
12418 "GET / HTTP/1.1\r\n"
12419 "Host: www.example.com\r\n"
12420 "Connection: keep-alive\r\n\r\n");
12421 const MockWrite kGetAuth(
12422 "GET / HTTP/1.1\r\n"
12423 "Host: www.example.com\r\n"
12424 "Connection: keep-alive\r\n"
12425 "Authorization: auth_token\r\n\r\n");
12426
12427 const MockRead kServerChallenge(
12428 "HTTP/1.1 401 Unauthorized\r\n"
12429 "WWW-Authenticate: Mock realm=server\r\n"
12430 "Content-Type: text/html; charset=iso-8859-1\r\n"
12431 "Content-Length: 14\r\n\r\n"
12432 "Unauthorized\r\n");
12433 const MockRead kSuccess(
12434 "HTTP/1.1 200 OK\r\n"
12435 "Content-Type: text/html; charset=iso-8859-1\r\n"
12436 "Content-Length: 3\r\n\r\n"
12437 "Yes");
12438
12439 MockWrite writes[] = {
12440 // First round
12441 kGet,
12442 // Second round
12443 kGetAuth,
12444 // Third round
12445 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012446 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012447 kGetAuth,
12448 // Competing request
12449 kGet,
[email protected]c871bce92010-07-15 21:51:1412450 };
12451 MockRead reads[] = {
12452 // First round
12453 kServerChallenge,
12454 // Second round
12455 kServerChallenge,
12456 // Third round
[email protected]eca50e122010-09-11 14:03:3012457 kServerChallenge,
12458 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412459 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012460 // Competing response
12461 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412462 };
12463 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12464 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712465 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412466
thestig9d3bb0c2015-01-24 00:49:5112467 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012468
12469 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412470 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012471 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412472 if (rv == ERR_IO_PENDING)
12473 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112474 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612475 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212476 ASSERT_TRUE(response);
12477 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812478 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112479 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12480 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412481
[email protected]7ef4cbbb2011-02-06 11:19:1012482 // In between rounds, another request comes in for the same domain.
12483 // It should not be able to grab the TCP socket that trans has already
12484 // claimed.
bnc691fda62016-08-12 00:43:1612485 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112486 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012487 rv = trans_compete.Start(&request, callback_compete.callback(),
12488 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012490 // callback_compete.WaitForResult at this point would stall forever,
12491 // since the HttpNetworkTransaction does not release the request back to
12492 // the pool until after authentication completes.
12493
12494 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412495 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612496 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412497 if (rv == ERR_IO_PENDING)
12498 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112499 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612500 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212501 ASSERT_TRUE(response);
12502 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812503 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112504 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12505 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412506
[email protected]7ef4cbbb2011-02-06 11:19:1012507 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412508 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612509 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412510 if (rv == ERR_IO_PENDING)
12511 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112512 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612513 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212514 ASSERT_TRUE(response);
12515 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812516 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112517 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12518 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012519
[email protected]7ef4cbbb2011-02-06 11:19:1012520 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012521 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612522 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012523 if (rv == ERR_IO_PENDING)
12524 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112525 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612526 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212527 ASSERT_TRUE(response);
12528 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812529 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012530
asanka463ca4262016-11-16 02:34:3112531 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12532 // auth handler should transition to a DONE state in concert with the remote
12533 // server. But that's not something we can test here with a mock handler.
12534 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12535 auth_handler->state());
12536
[email protected]7ef4cbbb2011-02-06 11:19:1012537 // Read the body since the fourth round was successful. This will also
12538 // release the socket back to the pool.
12539 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612540 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012541 if (rv == ERR_IO_PENDING)
12542 rv = callback.WaitForResult();
12543 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612544 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012545 EXPECT_EQ(0, rv);
12546 // There are still 0 idle sockets, since the trans_compete transaction
12547 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812548 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012549
12550 // The competing request can now finish. Wait for the headers and then
12551 // read the body.
12552 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112553 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612554 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012555 if (rv == ERR_IO_PENDING)
12556 rv = callback.WaitForResult();
12557 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612558 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012559 EXPECT_EQ(0, rv);
12560
12561 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812562 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412563}
12564
[email protected]65041fa2010-05-21 06:56:5312565// This tests the case that a request is issued via http instead of spdy after
12566// npn is negotiated.
bncd16676a2016-07-20 16:23:0112567TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312568 HttpRequestInfo request;
12569 request.method = "GET";
bncce36dca22015-04-21 22:11:2312570 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312571
12572 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312573 MockWrite(
12574 "GET / HTTP/1.1\r\n"
12575 "Host: www.example.org\r\n"
12576 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312577 };
12578
12579 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212580 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312581 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212582 MockRead("\r\n"),
12583 MockRead("hello world"),
12584 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312585 };
12586
[email protected]8ddf8322012-02-23 18:08:0612587 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612588 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312589
[email protected]bb88e1d32013-05-03 23:11:0712590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312591
12592 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12593 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712594 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312595
[email protected]49639fa2011-12-20 23:22:4112596 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312597
danakj1fd259a02016-04-16 03:17:0912598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312600
tfarina42834112016-09-22 13:38:2012601 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312602
robpercival214763f2016-07-01 23:27:0112603 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12604 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312605
bnc691fda62016-08-12 00:43:1612606 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212607 ASSERT_TRUE(response);
12608 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312609 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12610
12611 std::string response_data;
bnc691fda62016-08-12 00:43:1612612 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312613 EXPECT_EQ("hello world", response_data);
12614
12615 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212616 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312617}
[email protected]26ef6582010-06-24 02:30:4712618
bnc55ff9da2015-08-19 18:42:3512619// Simulate the SSL handshake completing with an NPN negotiation followed by an
12620// immediate server closing of the socket.
12621// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112622TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712623 HttpRequestInfo request;
12624 request.method = "GET";
bncce36dca22015-04-21 22:11:2312625 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712626
[email protected]8ddf8322012-02-23 18:08:0612627 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612628 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712630
bncdf80d44fd2016-07-15 20:27:4112631 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912632 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112633 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712634
12635 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612636 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712637 };
12638
rch8e6c6c42015-05-01 14:05:1312639 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12640 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712641 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712642
[email protected]49639fa2011-12-20 23:22:4112643 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712644
danakj1fd259a02016-04-16 03:17:0912645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712647
tfarina42834112016-09-22 13:38:2012648 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12650 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712651}
[email protected]65d34382010-07-01 18:12:2612652
[email protected]795cbf82013-07-22 09:37:2712653// A subclass of HttpAuthHandlerMock that records the request URL when
12654// it gets it. This is needed since the auth handler may get destroyed
12655// before we get a chance to query it.
12656class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12657 public:
12658 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12659
dchengb03027d2014-10-21 12:00:2012660 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712661
12662 protected:
dchengb03027d2014-10-21 12:00:2012663 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12664 const HttpRequestInfo* request,
12665 const CompletionCallback& callback,
12666 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712667 *url_ = request->url;
12668 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12669 credentials, request, callback, auth_token);
12670 }
12671
12672 private:
12673 GURL* url_;
12674};
12675
[email protected]8e6441ca2010-08-19 05:56:3812676// Test that if we cancel the transaction as the connection is completing, that
12677// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112678TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812679 // Setup everything about the connection to complete synchronously, so that
12680 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12681 // for is the callback from the HttpStreamRequest.
12682 // Then cancel the transaction.
12683 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612684 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812685 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612686 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12687 MockRead(SYNCHRONOUS, "hello world"),
12688 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812689 };
12690
[email protected]8e6441ca2010-08-19 05:56:3812691 HttpRequestInfo request;
12692 request.method = "GET";
bncce36dca22015-04-21 22:11:2312693 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812694
[email protected]bb88e1d32013-05-03 23:11:0712695 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912696 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812697 auto trans =
12698 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2712699
[email protected]8e6441ca2010-08-19 05:56:3812700 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12701 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712702 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812703
[email protected]49639fa2011-12-20 23:22:4112704 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812705
vishal.b62985ca92015-04-17 08:45:5112706 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112707 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812709 trans.reset(); // Cancel the transaction here.
12710
fdoray92e35a72016-06-10 15:54:5512711 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012712}
12713
[email protected]ecab6e052014-05-16 14:58:1212714// Test that if a transaction is cancelled after receiving the headers, the
12715// stream is drained properly and added back to the socket pool. The main
12716// purpose of this test is to make sure that an HttpStreamParser can be read
12717// from after the HttpNetworkTransaction and the objects it owns have been
12718// deleted.
12719// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112720TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212721 MockRead data_reads[] = {
12722 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12723 MockRead(ASYNC, "Content-Length: 2\r\n"),
12724 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12725 MockRead(ASYNC, "1"),
12726 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12727 // HttpNetworkTransaction has been deleted.
12728 MockRead(ASYNC, "2"),
12729 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12730 };
12731 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12732 session_deps_.socket_factory->AddSocketDataProvider(&data);
12733
danakj1fd259a02016-04-16 03:17:0912734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212735
12736 {
12737 HttpRequestInfo request;
12738 request.method = "GET";
bncce36dca22015-04-21 22:11:2312739 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212740
dcheng48459ac22014-08-26 00:46:4112741 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212742 TestCompletionCallback callback;
12743
tfarina42834112016-09-22 13:38:2012744 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212746 callback.WaitForResult();
12747
12748 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212749 ASSERT_TRUE(response);
12750 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212751 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12752
12753 // The transaction and HttpRequestInfo are deleted.
12754 }
12755
12756 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512757 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212758
12759 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112760 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212761}
12762
[email protected]76a505b2010-08-25 06:23:0012763// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112764TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312765 session_deps_.proxy_service =
12766 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112767 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712768 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912769 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012770
[email protected]76a505b2010-08-25 06:23:0012771 HttpRequestInfo request;
12772 request.method = "GET";
bncce36dca22015-04-21 22:11:2312773 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012774
12775 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312776 MockWrite(
12777 "GET http://www.example.org/ HTTP/1.1\r\n"
12778 "Host: www.example.org\r\n"
12779 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012780 };
12781
12782 MockRead data_reads1[] = {
12783 MockRead("HTTP/1.1 200 OK\r\n"),
12784 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12785 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612786 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012787 };
12788
12789 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12790 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012792
[email protected]49639fa2011-12-20 23:22:4112793 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012794
bnc691fda62016-08-12 00:43:1612795 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912796 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612797 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912798 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12799 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012800
bnc691fda62016-08-12 00:43:1612801 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012803
12804 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112805 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012806
bnc691fda62016-08-12 00:43:1612807 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212808 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012809
12810 EXPECT_TRUE(response->headers->IsKeepAlive());
12811 EXPECT_EQ(200, response->headers->response_code());
12812 EXPECT_EQ(100, response->headers->GetContentLength());
12813 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712814 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12815 HostPortPair::FromString("myproxy:70")),
12816 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912817 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12818 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12819 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012820 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012821
12822 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612823 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012824 TestLoadTimingNotReusedWithPac(load_timing_info,
12825 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012826}
12827
12828// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112829TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312830 session_deps_.proxy_service =
12831 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112832 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712833 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012835
[email protected]76a505b2010-08-25 06:23:0012836 HttpRequestInfo request;
12837 request.method = "GET";
bncce36dca22015-04-21 22:11:2312838 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012839
12840 // Since we have proxy, should try to establish tunnel.
12841 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712842 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12843 "Host: www.example.org:443\r\n"
12844 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012845
rsleevidb16bb02015-11-12 23:47:1712846 MockWrite("GET / HTTP/1.1\r\n"
12847 "Host: www.example.org\r\n"
12848 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012849 };
12850
12851 MockRead data_reads1[] = {
12852 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12853
12854 MockRead("HTTP/1.1 200 OK\r\n"),
12855 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12856 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612857 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012858 };
12859
12860 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12861 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712862 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612863 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712864 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012865
[email protected]49639fa2011-12-20 23:22:4112866 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012867
bnc691fda62016-08-12 00:43:1612868 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912869 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612870 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912871 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12872 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012873
bnc691fda62016-08-12 00:43:1612874 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012876
12877 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112878 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612879 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012880 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012881 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012882 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12883 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012884 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012885 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012886 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12887 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012888
bnc691fda62016-08-12 00:43:1612889 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212890 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012891
12892 EXPECT_TRUE(response->headers->IsKeepAlive());
12893 EXPECT_EQ(200, response->headers->response_code());
12894 EXPECT_EQ(100, response->headers->GetContentLength());
12895 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12896 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712897 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12898 HostPortPair::FromString("myproxy:70")),
12899 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912900 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12901 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12902 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012903
12904 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612905 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012906 TestLoadTimingNotReusedWithPac(load_timing_info,
12907 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012908}
12909
rsleevidb16bb02015-11-12 23:47:1712910// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12911// literal host.
bncd16676a2016-07-20 16:23:0112912TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712913 session_deps_.proxy_service =
12914 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12915 BoundTestNetLog log;
12916 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712918
12919 HttpRequestInfo request;
12920 request.method = "GET";
12921 request.url = GURL("https://[::1]:443/");
12922
12923 // Since we have proxy, should try to establish tunnel.
12924 MockWrite data_writes1[] = {
12925 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12926 "Host: [::1]:443\r\n"
12927 "Proxy-Connection: keep-alive\r\n\r\n"),
12928
12929 MockWrite("GET / HTTP/1.1\r\n"
12930 "Host: [::1]\r\n"
12931 "Connection: keep-alive\r\n\r\n"),
12932 };
12933
12934 MockRead data_reads1[] = {
12935 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12936
12937 MockRead("HTTP/1.1 200 OK\r\n"),
12938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12939 MockRead("Content-Length: 100\r\n\r\n"),
12940 MockRead(SYNCHRONOUS, OK),
12941 };
12942
12943 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12944 data_writes1, arraysize(data_writes1));
12945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12946 SSLSocketDataProvider ssl(ASYNC, OK);
12947 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12948
12949 TestCompletionCallback callback1;
12950
bnc691fda62016-08-12 00:43:1612951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712952
bnc691fda62016-08-12 00:43:1612953 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712955
12956 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112957 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712958 TestNetLogEntry::List entries;
12959 log.GetEntries(&entries);
12960 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012961 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12962 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712963 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012964 entries, pos,
12965 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12966 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712967
bnc691fda62016-08-12 00:43:1612968 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212969 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712970
12971 EXPECT_TRUE(response->headers->IsKeepAlive());
12972 EXPECT_EQ(200, response->headers->response_code());
12973 EXPECT_EQ(100, response->headers->GetContentLength());
12974 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12975 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712976 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12977 HostPortPair::FromString("myproxy:70")),
12978 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712979
12980 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612981 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712982 TestLoadTimingNotReusedWithPac(load_timing_info,
12983 CONNECT_TIMING_HAS_SSL_TIMES);
12984}
12985
[email protected]76a505b2010-08-25 06:23:0012986// Test a basic HTTPS GET request through a proxy, but the server hangs up
12987// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112988TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312989 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112990 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712991 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012993
[email protected]76a505b2010-08-25 06:23:0012994 HttpRequestInfo request;
12995 request.method = "GET";
bncce36dca22015-04-21 22:11:2312996 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012997
12998 // Since we have proxy, should try to establish tunnel.
12999 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713000 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13001 "Host: www.example.org:443\r\n"
13002 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013003
rsleevidb16bb02015-11-12 23:47:1713004 MockWrite("GET / HTTP/1.1\r\n"
13005 "Host: www.example.org\r\n"
13006 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013007 };
13008
13009 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613010 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013011 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613012 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013013 };
13014
13015 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13016 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713017 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613018 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713019 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013020
[email protected]49639fa2011-12-20 23:22:4113021 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013022
bnc691fda62016-08-12 00:43:1613023 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013024
bnc691fda62016-08-12 00:43:1613025 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113026 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013027
13028 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113029 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613030 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013031 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013032 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013033 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13034 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013035 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013036 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013037 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13038 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013039}
13040
[email protected]749eefa82010-09-13 22:14:0313041// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113042TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113043 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913044 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113045 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313046
bnc42331402016-07-25 13:36:1513047 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113048 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313049 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113050 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313051 };
13052
rch8e6c6c42015-05-01 14:05:1313053 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13054 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713055 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313056
[email protected]8ddf8322012-02-23 18:08:0613057 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613058 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313060
danakj1fd259a02016-04-16 03:17:0913061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313062
13063 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313064 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013065 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313066 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713067 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513068 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313069
13070 HttpRequestInfo request;
13071 request.method = "GET";
bncce36dca22015-04-21 22:11:2313072 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313073
13074 // This is the important line that marks this as a preconnect.
13075 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13076
bnc691fda62016-08-12 00:43:1613077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313078
[email protected]41d64e82013-07-03 22:44:2613079 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013080 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113081 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13082 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313083}
13084
[email protected]73b8dd222010-11-11 19:55:2413085// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613086// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213087void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713088 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913089 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713090 request_info.url = GURL("https://www.example.com/");
13091 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913092 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713093
[email protected]8ddf8322012-02-23 18:08:0613094 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913095 MockWrite data_writes[] = {
13096 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413097 };
ttuttle859dc7a2015-04-23 19:42:2913098 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713099 session_deps_.socket_factory->AddSocketDataProvider(&data);
13100 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413101
danakj1fd259a02016-04-16 03:17:0913102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413104
[email protected]49639fa2011-12-20 23:22:4113105 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013106 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913107 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413108 rv = callback.WaitForResult();
13109 ASSERT_EQ(error, rv);
13110}
13111
bncd16676a2016-07-20 16:23:0113112TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413113 // Just check a grab bag of cert errors.
13114 static const int kErrors[] = {
13115 ERR_CERT_COMMON_NAME_INVALID,
13116 ERR_CERT_AUTHORITY_INVALID,
13117 ERR_CERT_DATE_INVALID,
13118 };
13119 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613120 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13121 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413122 }
13123}
13124
[email protected]bd0b6772011-01-11 19:59:3013125// Ensure that a client certificate is removed from the SSL client auth
13126// cache when:
13127// 1) No proxy is involved.
13128// 2) TLS False Start is disabled.
13129// 3) The initial TLS handshake requests a client certificate.
13130// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113131TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913132 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713133 request_info.url = GURL("https://www.example.com/");
13134 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913135 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713136
[email protected]bd0b6772011-01-11 19:59:3013137 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113138 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013139
13140 // [ssl_]data1 contains the data for the first SSL handshake. When a
13141 // CertificateRequest is received for the first time, the handshake will
13142 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913143 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013144 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913146 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713147 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013148
13149 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13150 // False Start is not being used, the result of the SSL handshake will be
13151 // returned as part of the SSLClientSocket::Connect() call. This test
13152 // matches the result of a server sending a handshake_failure alert,
13153 // rather than a Finished message, because it requires a client
13154 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913155 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013156 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713157 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913158 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713159 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013160
13161 // [ssl_]data3 contains the data for the third SSL handshake. When a
13162 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213163 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13164 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013165 // of the HttpNetworkTransaction. Because this test failure is due to
13166 // requiring a client certificate, this fallback handshake should also
13167 // fail.
ttuttle859dc7a2015-04-23 19:42:2913168 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013169 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913171 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713172 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013173
[email protected]80c75f682012-05-26 16:22:1713174 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13175 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213176 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13177 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713178 // of the HttpNetworkTransaction. Because this test failure is due to
13179 // requiring a client certificate, this fallback handshake should also
13180 // fail.
ttuttle859dc7a2015-04-23 19:42:2913181 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713182 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713183 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913184 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713185 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713186
danakj1fd259a02016-04-16 03:17:0913187 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613188 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013189
[email protected]bd0b6772011-01-11 19:59:3013190 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113191 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013192 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113193 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013194
13195 // Complete the SSL handshake, which should abort due to requiring a
13196 // client certificate.
13197 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113198 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013199
13200 // Indicate that no certificate should be supplied. From the perspective
13201 // of SSLClientCertCache, NULL is just as meaningful as a real
13202 // certificate, so this is the same as supply a
13203 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613204 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113205 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013206
13207 // Ensure the certificate was added to the client auth cache before
13208 // allowing the connection to continue restarting.
13209 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413210 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113211 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413212 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213213 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013214
13215 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713216 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13217 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013218 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113219 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013220
13221 // Ensure that the client certificate is removed from the cache on a
13222 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113223 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413224 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013225}
13226
13227// Ensure that a client certificate is removed from the SSL client auth
13228// cache when:
13229// 1) No proxy is involved.
13230// 2) TLS False Start is enabled.
13231// 3) The initial TLS handshake requests a client certificate.
13232// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113233TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913234 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713235 request_info.url = GURL("https://www.example.com/");
13236 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913237 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713238
[email protected]bd0b6772011-01-11 19:59:3013239 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113240 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013241
13242 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13243 // return successfully after reading up to the peer's Certificate message.
13244 // This is to allow the caller to call SSLClientSocket::Write(), which can
13245 // enqueue application data to be sent in the same packet as the
13246 // ChangeCipherSpec and Finished messages.
13247 // The actual handshake will be finished when SSLClientSocket::Read() is
13248 // called, which expects to process the peer's ChangeCipherSpec and
13249 // Finished messages. If there was an error negotiating with the peer,
13250 // such as due to the peer requiring a client certificate when none was
13251 // supplied, the alert sent by the peer won't be processed until Read() is
13252 // called.
13253
13254 // Like the non-False Start case, when a client certificate is requested by
13255 // the peer, the handshake is aborted during the Connect() call.
13256 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913257 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013258 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713259 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913260 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713261 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013262
13263 // When a client certificate is supplied, Connect() will not be aborted
13264 // when the peer requests the certificate. Instead, the handshake will
13265 // artificially succeed, allowing the caller to write the HTTP request to
13266 // the socket. The handshake messages are not processed until Read() is
13267 // called, which then detects that the handshake was aborted, due to the
13268 // peer sending a handshake_failure because it requires a client
13269 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913270 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013271 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713272 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913273 MockRead data2_reads[] = {
13274 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013275 };
ttuttle859dc7a2015-04-23 19:42:2913276 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713277 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013278
13279 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713280 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13281 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913282 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013283 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713284 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913285 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713286 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013287
[email protected]80c75f682012-05-26 16:22:1713288 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13289 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913290 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713291 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913293 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713294 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713295
[email protected]7799de12013-05-30 05:52:5113296 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913297 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113298 ssl_data5.cert_request_info = cert_request.get();
13299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913300 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113301 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13302
danakj1fd259a02016-04-16 03:17:0913303 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013305
[email protected]bd0b6772011-01-11 19:59:3013306 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113307 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013308 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113309 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013310
13311 // Complete the SSL handshake, which should abort due to requiring a
13312 // client certificate.
13313 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113314 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013315
13316 // Indicate that no certificate should be supplied. From the perspective
13317 // of SSLClientCertCache, NULL is just as meaningful as a real
13318 // certificate, so this is the same as supply a
13319 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613320 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113321 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013322
13323 // Ensure the certificate was added to the client auth cache before
13324 // allowing the connection to continue restarting.
13325 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413326 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113327 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413328 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213329 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013330
[email protected]bd0b6772011-01-11 19:59:3013331 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713332 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13333 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013334 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113335 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013336
13337 // Ensure that the client certificate is removed from the cache on a
13338 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113339 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413340 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013341}
13342
[email protected]8c405132011-01-11 22:03:1813343// Ensure that a client certificate is removed from the SSL client auth
13344// cache when:
13345// 1) An HTTPS proxy is involved.
13346// 3) The HTTPS proxy requests a client certificate.
13347// 4) The client supplies an invalid/unacceptable certificate for the
13348// proxy.
13349// The test is repeated twice, first for connecting to an HTTPS endpoint,
13350// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113351TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313352 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113353 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713354 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813355
13356 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113357 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813358
13359 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13360 // [ssl_]data[1-3]. Rather than represending the endpoint
13361 // (www.example.com:443), they represent failures with the HTTPS proxy
13362 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913363 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813364 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913366 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713367 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813368
ttuttle859dc7a2015-04-23 19:42:2913369 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813370 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913372 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713373 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813374
[email protected]80c75f682012-05-26 16:22:1713375 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13376#if 0
ttuttle859dc7a2015-04-23 19:42:2913377 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813378 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913380 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713381 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713382#endif
[email protected]8c405132011-01-11 22:03:1813383
ttuttle859dc7a2015-04-23 19:42:2913384 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813385 requests[0].url = GURL("https://www.example.com/");
13386 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913387 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813388
13389 requests[1].url = GURL("http://www.example.com/");
13390 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913391 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813392
13393 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713394 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813397
13398 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113399 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013400 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113401 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813402
13403 // Complete the SSL handshake, which should abort due to requiring a
13404 // client certificate.
13405 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113406 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813407
13408 // Indicate that no certificate should be supplied. From the perspective
13409 // of SSLClientCertCache, NULL is just as meaningful as a real
13410 // certificate, so this is the same as supply a
13411 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613412 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113413 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813414
13415 // Ensure the certificate was added to the client auth cache before
13416 // allowing the connection to continue restarting.
13417 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413418 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113419 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413420 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213421 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813422 // Ensure the certificate was NOT cached for the endpoint. This only
13423 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113424 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413425 HostPortPair("www.example.com", 443), &client_cert,
13426 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813427
13428 // Restart the handshake. This will consume ssl_data2, which fails, and
13429 // then consume ssl_data3, which should also fail. The result code is
13430 // checked against what ssl_data3 should return.
13431 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113432 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813433
13434 // Now that the new handshake has failed, ensure that the client
13435 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113436 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413437 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113438 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413439 HostPortPair("www.example.com", 443), &client_cert,
13440 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813441 }
13442}
13443
bncd16676a2016-07-20 16:23:0113444TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613445 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813446 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913447 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613448
bnc032658ba2016-09-26 18:17:1513449 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613450
bncdf80d44fd2016-07-15 20:27:4113451 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913452 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813453 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113454 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713455 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613456 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113457 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613458 };
bnc42331402016-07-25 13:36:1513459 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113460 SpdySerializedFrame host1_resp_body(
13461 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513462 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113463 SpdySerializedFrame host2_resp_body(
13464 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613465 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113466 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13467 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313468 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613469 };
13470
eroman36d84e54432016-03-17 03:23:0213471 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213472 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313473 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13474 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713475 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613476
[email protected]aa22b242011-11-16 18:58:2913477 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613478 HttpRequestInfo request1;
13479 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313480 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613481 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013482 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613483
tfarina42834112016-09-22 13:38:2013484 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13486 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613487
13488 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213489 ASSERT_TRUE(response);
13490 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213491 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613492
13493 std::string response_data;
robpercival214763f2016-07-01 23:27:0113494 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613495 EXPECT_EQ("hello!", response_data);
13496
bnca4d611d2016-09-22 19:55:3713497 // Preload mail.example.com into HostCache.
13498 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013499 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613500 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013501 std::unique_ptr<HostResolver::Request> request;
13502 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13503 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013504 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713506 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113507 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613508
13509 HttpRequestInfo request2;
13510 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713511 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613512 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013513 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613514
tfarina42834112016-09-22 13:38:2013515 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13517 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613518
13519 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213520 ASSERT_TRUE(response);
13521 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213522 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613523 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213524 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113525 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613526 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613527}
13528
bncd16676a2016-07-20 16:23:0113529TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213530 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813531 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913532 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213533
bnc032658ba2016-09-26 18:17:1513534 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213535
bncdf80d44fd2016-07-15 20:27:4113536 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913537 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813538 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113539 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713540 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213541 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113542 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213543 };
bnc42331402016-07-25 13:36:1513544 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113545 SpdySerializedFrame host1_resp_body(
13546 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513547 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113548 SpdySerializedFrame host2_resp_body(
13549 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213550 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113551 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13552 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313553 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213554 };
13555
eroman36d84e54432016-03-17 03:23:0213556 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213557 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313558 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13559 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713560 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213561
13562 TestCompletionCallback callback;
13563 HttpRequestInfo request1;
13564 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313565 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213566 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013567 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213568
tfarina42834112016-09-22 13:38:2013569 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113570 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13571 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213572
13573 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213574 ASSERT_TRUE(response);
13575 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213576 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213577
13578 std::string response_data;
robpercival214763f2016-07-01 23:27:0113579 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213580 EXPECT_EQ("hello!", response_data);
13581
13582 HttpRequestInfo request2;
13583 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713584 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213585 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013586 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213587
tfarina42834112016-09-22 13:38:2013588 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113589 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13590 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213591
13592 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213593 ASSERT_TRUE(response);
13594 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213595 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213596 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213597 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113598 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213599 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213600}
13601
bnc8016c1f2017-03-31 02:11:2913602// Regression test for https://crbug.com/546991.
13603// The server might not be able to serve an IP pooled request, and might send a
13604// 421 Misdirected Request response status to indicate this.
13605// HttpNetworkTransaction should reset the request and retry without IP pooling.
13606TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13607 // Two hosts resolve to the same IP address.
13608 const std::string ip_addr = "1.2.3.4";
13609 IPAddress ip;
13610 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13611 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13612
bnc87dcefc2017-05-25 12:47:5813613 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913614 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13615 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13616
13617 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13618
13619 // Two requests on the first connection.
13620 SpdySerializedFrame req1(
13621 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13622 spdy_util_.UpdateWithStreamDestruction(1);
13623 SpdySerializedFrame req2(
13624 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13625 SpdySerializedFrame rst(
13626 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13627 MockWrite writes1[] = {
13628 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13629 CreateMockWrite(rst, 6),
13630 };
13631
13632 // The first one succeeds, the second gets error 421 Misdirected Request.
13633 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13634 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13635 SpdyHeaderBlock response_headers;
13636 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13637 SpdySerializedFrame resp2(
13638 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13639 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13640 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13641
13642 MockConnect connect1(ASYNC, OK, peer_addr);
13643 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13644 arraysize(writes1));
13645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13646
13647 AddSSLSocketData();
13648
13649 // Retry the second request on a second connection.
13650 SpdyTestUtil spdy_util2;
13651 SpdySerializedFrame req3(
13652 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13653 MockWrite writes2[] = {
13654 CreateMockWrite(req3, 0),
13655 };
13656
13657 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13658 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13659 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13660 MockRead(ASYNC, 0, 3)};
13661
13662 MockConnect connect2(ASYNC, OK, peer_addr);
13663 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13664 arraysize(writes2));
13665 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13666
13667 AddSSLSocketData();
13668
13669 // Preload mail.example.org into HostCache.
13670 HostPortPair host_port("mail.example.org", 443);
13671 HostResolver::RequestInfo resolve_info(host_port);
13672 AddressList ignored;
13673 std::unique_ptr<HostResolver::Request> request;
13674 TestCompletionCallback callback;
13675 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13676 &ignored, callback.callback(),
13677 &request, NetLogWithSource());
13678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13679 rv = callback.WaitForResult();
13680 EXPECT_THAT(rv, IsOk());
13681
13682 HttpRequestInfo request1;
13683 request1.method = "GET";
13684 request1.url = GURL("https://www.example.org/");
13685 request1.load_flags = 0;
13686 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13687
13688 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13690 rv = callback.WaitForResult();
13691 EXPECT_THAT(rv, IsOk());
13692
13693 const HttpResponseInfo* response = trans1.GetResponseInfo();
13694 ASSERT_TRUE(response);
13695 ASSERT_TRUE(response->headers);
13696 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13697 EXPECT_TRUE(response->was_fetched_via_spdy);
13698 EXPECT_TRUE(response->was_alpn_negotiated);
13699 std::string response_data;
13700 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13701 EXPECT_EQ("hello!", response_data);
13702
13703 HttpRequestInfo request2;
13704 request2.method = "GET";
13705 request2.url = GURL("https://mail.example.org/");
13706 request2.load_flags = 0;
13707 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13708
13709 BoundTestNetLog log;
13710 rv = trans2.Start(&request2, callback.callback(), log.bound());
13711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13712 rv = callback.WaitForResult();
13713 EXPECT_THAT(rv, IsOk());
13714
13715 response = trans2.GetResponseInfo();
13716 ASSERT_TRUE(response);
13717 ASSERT_TRUE(response->headers);
13718 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13719 EXPECT_TRUE(response->was_fetched_via_spdy);
13720 EXPECT_TRUE(response->was_alpn_negotiated);
13721 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13722 EXPECT_EQ("hello!", response_data);
13723
13724 TestNetLogEntry::List entries;
13725 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5913726 ExpectLogContainsSomewhere(
13727 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2913728 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5913729}
13730
13731// Test that HTTP 421 responses are properly returned to the caller if received
13732// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
13733// portions of the response.
13734TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
13735 // Two hosts resolve to the same IP address.
13736 const std::string ip_addr = "1.2.3.4";
13737 IPAddress ip;
13738 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13739 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13740
bnc87dcefc2017-05-25 12:47:5813741 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5913742 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13743 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13744
13745 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13746
13747 // Two requests on the first connection.
13748 SpdySerializedFrame req1(
13749 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13750 spdy_util_.UpdateWithStreamDestruction(1);
13751 SpdySerializedFrame req2(
13752 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13753 SpdySerializedFrame rst(
13754 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13755 MockWrite writes1[] = {
13756 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13757 CreateMockWrite(rst, 6),
13758 };
13759
13760 // The first one succeeds, the second gets error 421 Misdirected Request.
13761 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13762 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13763 SpdyHeaderBlock response_headers;
13764 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13765 SpdySerializedFrame resp2(
13766 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
13767 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13768 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13769
13770 MockConnect connect1(ASYNC, OK, peer_addr);
13771 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13772 arraysize(writes1));
13773 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13774
13775 AddSSLSocketData();
13776
13777 // Retry the second request on a second connection. It returns 421 Misdirected
13778 // Retry again.
13779 SpdyTestUtil spdy_util2;
13780 SpdySerializedFrame req3(
13781 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13782 MockWrite writes2[] = {
13783 CreateMockWrite(req3, 0),
13784 };
13785
13786 SpdySerializedFrame resp3(
13787 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
13788 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13789 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13790 MockRead(ASYNC, 0, 3)};
13791
13792 MockConnect connect2(ASYNC, OK, peer_addr);
13793 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13794 arraysize(writes2));
13795 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13796
13797 AddSSLSocketData();
13798
13799 // Preload mail.example.org into HostCache.
13800 HostPortPair host_port("mail.example.org", 443);
13801 HostResolver::RequestInfo resolve_info(host_port);
13802 AddressList ignored;
13803 std::unique_ptr<HostResolver::Request> request;
13804 TestCompletionCallback callback;
13805 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13806 &ignored, callback.callback(),
13807 &request, NetLogWithSource());
13808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13809 rv = callback.WaitForResult();
13810 EXPECT_THAT(rv, IsOk());
13811
13812 HttpRequestInfo request1;
13813 request1.method = "GET";
13814 request1.url = GURL("https://www.example.org/");
13815 request1.load_flags = 0;
13816 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13817
13818 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13820 rv = callback.WaitForResult();
13821 EXPECT_THAT(rv, IsOk());
13822
13823 const HttpResponseInfo* response = trans1.GetResponseInfo();
13824 ASSERT_TRUE(response);
13825 ASSERT_TRUE(response->headers);
13826 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13827 EXPECT_TRUE(response->was_fetched_via_spdy);
13828 EXPECT_TRUE(response->was_alpn_negotiated);
13829 std::string response_data;
13830 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13831 EXPECT_EQ("hello!", response_data);
13832
13833 HttpRequestInfo request2;
13834 request2.method = "GET";
13835 request2.url = GURL("https://mail.example.org/");
13836 request2.load_flags = 0;
13837 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13838
13839 BoundTestNetLog log;
13840 rv = trans2.Start(&request2, callback.callback(), log.bound());
13841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13842 rv = callback.WaitForResult();
13843 EXPECT_THAT(rv, IsOk());
13844
13845 // After a retry, the 421 Misdirected Request is reported back up to the
13846 // caller.
13847 response = trans2.GetResponseInfo();
13848 ASSERT_TRUE(response);
13849 ASSERT_TRUE(response->headers);
13850 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
13851 EXPECT_TRUE(response->was_fetched_via_spdy);
13852 EXPECT_TRUE(response->was_alpn_negotiated);
13853 EXPECT_TRUE(response->ssl_info.cert);
13854 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13855 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2913856}
13857
bnc6dcd8192017-05-25 20:11:5013858class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4613859 public:
13860 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5013861 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013862 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613863
dchengb03027d2014-10-21 12:00:2013864 int ResolveFromCache(const RequestInfo& info,
13865 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013866 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5013867 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4013868 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5013869 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613870 return rv;
13871 }
13872
[email protected]e3ceb682011-06-28 23:55:4613873 private:
[email protected]e3ceb682011-06-28 23:55:4613874 const HostPortPair host_port_;
13875};
13876
bncd16676a2016-07-20 16:23:0113877TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313878 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613879 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnc6dcd8192017-05-25 20:11:5013880 session_deps_.host_resolver = base::MakeUnique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3713881 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0913882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613883
bnc032658ba2016-09-26 18:17:1513884 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613885
bncdf80d44fd2016-07-15 20:27:4113886 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913887 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813888 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113889 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713890 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613891 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113892 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613893 };
bnc42331402016-07-25 13:36:1513894 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113895 SpdySerializedFrame host1_resp_body(
13896 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513897 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113898 SpdySerializedFrame host2_resp_body(
13899 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613900 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113901 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13902 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313903 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613904 };
13905
eroman36d84e54432016-03-17 03:23:0213906 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213907 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313908 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13909 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713910 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613911
[email protected]aa22b242011-11-16 18:58:2913912 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613913 HttpRequestInfo request1;
13914 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313915 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613916 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013917 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613918
tfarina42834112016-09-22 13:38:2013919 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13921 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613922
13923 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213924 ASSERT_TRUE(response);
13925 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213926 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613927
13928 std::string response_data;
robpercival214763f2016-07-01 23:27:0113929 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613930 EXPECT_EQ("hello!", response_data);
13931
13932 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713933 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613934 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013935 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5013936 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13937 &ignored, callback.callback(),
13938 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713940 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113941 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613942
13943 HttpRequestInfo request2;
13944 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713945 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613946 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013947 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613948
tfarina42834112016-09-22 13:38:2013949 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13951 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613952
13953 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213954 ASSERT_TRUE(response);
13955 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213956 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613957 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213958 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113959 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613960 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613961}
13962
bncd16676a2016-07-20 16:23:0113963TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313964 const std::string https_url = "https://www.example.org:8080/";
13965 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413966
13967 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113968 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913969 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413970
13971 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113972 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413973 };
13974
bnc42331402016-07-25 13:36:1513975 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113976 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13977 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913978 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413979
rch8e6c6c42015-05-01 14:05:1313980 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13981 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413982 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713983 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413984
13985 // HTTP GET for the HTTP URL
13986 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313987 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413988 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313989 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413990 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413991 };
13992
13993 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313994 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13995 MockRead(ASYNC, 2, "hello"),
13996 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413997 };
13998
rch8e6c6c42015-05-01 14:05:1313999 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14000 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414001
[email protected]8450d722012-07-02 19:14:0414002 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614003 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714004 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14005 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14006 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414007
danakj1fd259a02016-04-16 03:17:0914008 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414009
14010 // Start the first transaction to set up the SpdySession
14011 HttpRequestInfo request1;
14012 request1.method = "GET";
14013 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414014 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014015 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414016 TestCompletionCallback callback1;
14017 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014018 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514019 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414020
robpercival214763f2016-07-01 23:27:0114021 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414022 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14023
14024 // Now, start the HTTP request
14025 HttpRequestInfo request2;
14026 request2.method = "GET";
14027 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414028 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014029 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414030 TestCompletionCallback callback2;
14031 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014032 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514033 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414034
robpercival214763f2016-07-01 23:27:0114035 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414036 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14037}
14038
bnc5452e2a2015-05-08 16:27:4214039// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14040// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114041TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514042 url::SchemeHostPort server("https", "www.example.org", 443);
14043 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214044
bnc8bef8da22016-05-30 01:28:2514045 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214046 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614047 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14049
14050 // No data should be read from the alternative, because HTTP/1.1 is
14051 // negotiated.
14052 StaticSocketDataProvider data;
14053 session_deps_.socket_factory->AddSocketDataProvider(&data);
14054
14055 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614056 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214057 // mocked. This way the request relies on the alternate Job.
14058 StaticSocketDataProvider data_refused;
14059 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14060 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14061
zhongyi3d4a55e72016-04-22 20:36:4614062 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914063 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014064 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214065 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114066 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214067 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614068 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014069 expiration);
bnc5452e2a2015-05-08 16:27:4214070
bnc5452e2a2015-05-08 16:27:4214071 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614072 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214073 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514074 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214075 TestCompletionCallback callback;
14076
14077 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214078 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014079 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214080 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214081}
14082
bnc40448a532015-05-11 19:13:1414083// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614084// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414085// succeeds, the request should succeed, even if the latter fails because
14086// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114087TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514088 url::SchemeHostPort server("https", "www.example.org", 443);
14089 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414090
14091 // Negotiate HTTP/1.1 with alternative.
14092 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614093 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414094 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14095
14096 // No data should be read from the alternative, because HTTP/1.1 is
14097 // negotiated.
14098 StaticSocketDataProvider data;
14099 session_deps_.socket_factory->AddSocketDataProvider(&data);
14100
zhongyi3d4a55e72016-04-22 20:36:4614101 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414102 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614103 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414104 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14105
14106 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514107 MockWrite("GET / HTTP/1.1\r\n"
14108 "Host: www.example.org\r\n"
14109 "Connection: keep-alive\r\n\r\n"),
14110 MockWrite("GET /second HTTP/1.1\r\n"
14111 "Host: www.example.org\r\n"
14112 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414113 };
14114
14115 MockRead http_reads[] = {
14116 MockRead("HTTP/1.1 200 OK\r\n"),
14117 MockRead("Content-Type: text/html\r\n"),
14118 MockRead("Content-Length: 6\r\n\r\n"),
14119 MockRead("foobar"),
14120 MockRead("HTTP/1.1 200 OK\r\n"),
14121 MockRead("Content-Type: text/html\r\n"),
14122 MockRead("Content-Length: 7\r\n\r\n"),
14123 MockRead("another"),
14124 };
14125 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14126 http_writes, arraysize(http_writes));
14127 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14128
zhongyi3d4a55e72016-04-22 20:36:4614129 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014131 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414132 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114133 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214134 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614135 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014136 expiration);
bnc40448a532015-05-11 19:13:1414137
14138 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14139 HttpRequestInfo request1;
14140 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514141 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414142 request1.load_flags = 0;
14143 TestCompletionCallback callback1;
14144
tfarina42834112016-09-22 13:38:2014145 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414146 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114147 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414148
14149 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214150 ASSERT_TRUE(response1);
14151 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414152 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14153
14154 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114155 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414156 EXPECT_EQ("foobar", response_data1);
14157
14158 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14159 // for alternative service.
14160 EXPECT_TRUE(
14161 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14162
zhongyi3d4a55e72016-04-22 20:36:4614163 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414164 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614165 // to server.
bnc40448a532015-05-11 19:13:1414166 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14167 HttpRequestInfo request2;
14168 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514169 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414170 request2.load_flags = 0;
14171 TestCompletionCallback callback2;
14172
tfarina42834112016-09-22 13:38:2014173 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414174 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114175 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414176
14177 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214178 ASSERT_TRUE(response2);
14179 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414180 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14181
14182 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114183 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414184 EXPECT_EQ("another", response_data2);
14185}
14186
bnc5452e2a2015-05-08 16:27:4214187// Alternative service requires HTTP/2 (or SPDY), but there is already a
14188// HTTP/1.1 socket open to the alternative server. That socket should not be
14189// used.
bncd16676a2016-07-20 16:23:0114190TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614191 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214192 HostPortPair alternative("alternative.example.org", 443);
14193 std::string origin_url = "https://origin.example.org:443";
14194 std::string alternative_url = "https://alternative.example.org:443";
14195
14196 // Negotiate HTTP/1.1 with alternative.example.org.
14197 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614198 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14200
14201 // HTTP/1.1 data for |request1| and |request2|.
14202 MockWrite http_writes[] = {
14203 MockWrite(
14204 "GET / HTTP/1.1\r\n"
14205 "Host: alternative.example.org\r\n"
14206 "Connection: keep-alive\r\n\r\n"),
14207 MockWrite(
14208 "GET / HTTP/1.1\r\n"
14209 "Host: alternative.example.org\r\n"
14210 "Connection: keep-alive\r\n\r\n"),
14211 };
14212
14213 MockRead http_reads[] = {
14214 MockRead(
14215 "HTTP/1.1 200 OK\r\n"
14216 "Content-Type: text/html; charset=iso-8859-1\r\n"
14217 "Content-Length: 40\r\n\r\n"
14218 "first HTTP/1.1 response from alternative"),
14219 MockRead(
14220 "HTTP/1.1 200 OK\r\n"
14221 "Content-Type: text/html; charset=iso-8859-1\r\n"
14222 "Content-Length: 41\r\n\r\n"
14223 "second HTTP/1.1 response from alternative"),
14224 };
14225 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14226 http_writes, arraysize(http_writes));
14227 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14228
14229 // This test documents that an alternate Job should not pool to an already
14230 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614231 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214232 StaticSocketDataProvider data_refused;
14233 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14234 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14235
zhongyi3d4a55e72016-04-22 20:36:4614236 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014238 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214239 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114240 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214241 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614242 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014243 expiration);
bnc5452e2a2015-05-08 16:27:4214244
14245 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214246 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614247 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214248 request1.method = "GET";
14249 request1.url = GURL(alternative_url);
14250 request1.load_flags = 0;
14251 TestCompletionCallback callback1;
14252
tfarina42834112016-09-22 13:38:2014253 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114254 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614255 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214256 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214257 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214258 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214259 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214260 EXPECT_FALSE(response1->was_fetched_via_spdy);
14261 std::string response_data1;
bnc691fda62016-08-12 00:43:1614262 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214263 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14264
14265 // Request for origin.example.org, which has an alternative service. This
14266 // will start two Jobs: the alternative looks for connections to pool to,
14267 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614268 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214269 // this request fails.
bnc5452e2a2015-05-08 16:27:4214270 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614271 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214272 request2.method = "GET";
14273 request2.url = GURL(origin_url);
14274 request2.load_flags = 0;
14275 TestCompletionCallback callback2;
14276
tfarina42834112016-09-22 13:38:2014277 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114278 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214279
14280 // Another transaction to alternative. This is to test that the HTTP/1.1
14281 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214282 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614283 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214284 request3.method = "GET";
14285 request3.url = GURL(alternative_url);
14286 request3.load_flags = 0;
14287 TestCompletionCallback callback3;
14288
tfarina42834112016-09-22 13:38:2014289 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114290 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614291 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214292 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214293 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214294 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214295 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214296 EXPECT_FALSE(response3->was_fetched_via_spdy);
14297 std::string response_data3;
bnc691fda62016-08-12 00:43:1614298 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214299 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14300}
14301
bncd16676a2016-07-20 16:23:0114302TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314303 const std::string https_url = "https://www.example.org:8080/";
14304 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414305
rdsmithebb50aa2015-11-12 03:44:3814306 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114307 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814308
[email protected]8450d722012-07-02 19:14:0414309 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314310 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114311 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414312 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114313 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914314 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114315 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214316 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914317
14318 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914319 SpdyHeaderBlock req2_block;
14320 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314321 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914322 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914323 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114324 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514325 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414326
14327 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114328 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14329 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414330 };
14331
bncdf80d44fd2016-07-15 20:27:4114332 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514333 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114334 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514335 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114336 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14337 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814338 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114339 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814340 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514341 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114342 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314343 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114344 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314345 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114346 CreateMockRead(wrapped_resp1, 4),
14347 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314348 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114349 CreateMockRead(resp2, 8),
14350 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314351 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14352 };
[email protected]8450d722012-07-02 19:14:0414353
mmenke666a6fea2015-12-19 04:16:3314354 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14355 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414356 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714357 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414358
rdsmith82957ad2015-09-16 19:42:0314359 session_deps_.proxy_service =
14360 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114361 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714362 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414363 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614364 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414366 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614367 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14369 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414370
danakj1fd259a02016-04-16 03:17:0914371 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414372
14373 // Start the first transaction to set up the SpdySession
14374 HttpRequestInfo request1;
14375 request1.method = "GET";
14376 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414377 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014378 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414379 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014380 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414381
mmenke666a6fea2015-12-19 04:16:3314382 // This pause is a hack to avoid running into https://crbug.com/497228.
14383 data1.RunUntilPaused();
14384 base::RunLoop().RunUntilIdle();
14385 data1.Resume();
robpercival214763f2016-07-01 23:27:0114386 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414387 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14388
[email protected]f6c63db52013-02-02 00:35:2214389 LoadTimingInfo load_timing_info1;
14390 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14391 TestLoadTimingNotReusedWithPac(load_timing_info1,
14392 CONNECT_TIMING_HAS_SSL_TIMES);
14393
mmenke666a6fea2015-12-19 04:16:3314394 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414395 HttpRequestInfo request2;
14396 request2.method = "GET";
14397 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414398 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014399 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414400 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014401 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414402
mmenke666a6fea2015-12-19 04:16:3314403 // This pause is a hack to avoid running into https://crbug.com/497228.
14404 data1.RunUntilPaused();
14405 base::RunLoop().RunUntilIdle();
14406 data1.Resume();
robpercival214763f2016-07-01 23:27:0114407 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314408
[email protected]8450d722012-07-02 19:14:0414409 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214410
14411 LoadTimingInfo load_timing_info2;
14412 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14413 // The established SPDY sessions is considered reused by the HTTP request.
14414 TestLoadTimingReusedWithPac(load_timing_info2);
14415 // HTTP requests over a SPDY session should have a different connection
14416 // socket_log_id than requests over a tunnel.
14417 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414418}
14419
[email protected]2d88e7d2012-07-19 17:55:1714420// Test that in the case where we have a SPDY session to a SPDY proxy
14421// that we do not pool other origins that resolve to the same IP when
14422// the certificate does not match the new origin.
14423// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114424TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314425 const std::string url1 = "http://www.example.org/";
14426 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714427 const std::string ip_addr = "1.2.3.4";
14428
rdsmithebb50aa2015-11-12 03:44:3814429 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114430 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814431
[email protected]2d88e7d2012-07-19 17:55:1714432 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614433 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314434 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114435 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514436 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714437
14438 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114439 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714440 };
14441
bnc42331402016-07-25 13:36:1514442 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114443 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714444 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114445 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14446 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714447 };
14448
mmenke666a6fea2015-12-19 04:16:3314449 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14450 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214451 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914452 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714453 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14454 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314455 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714456
14457 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114458 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914459 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714460
14461 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114462 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714463 };
14464
bnc42331402016-07-25 13:36:1514465 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114466 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14467 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314468 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714469
mmenke666a6fea2015-12-19 04:16:3314470 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14471 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714472 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314473 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714474
14475 // Set up a proxy config that sends HTTP requests to a proxy, and
14476 // all others direct.
14477 ProxyConfig proxy_config;
14478 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
bnc87dcefc2017-05-25 12:47:5814479 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
14480 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), nullptr,
14481 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714482
bncce36dca22015-04-21 22:11:2314483 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614484 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714485 // Load a valid cert. Note, that this does not need to
14486 // be valid for proxy because the MockSSLClientSocket does
14487 // not actually verify it. But SpdySession will use this
14488 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314489 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214490 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314491 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14492 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714493
14494 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614495 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14497 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714498
bnc87dcefc2017-05-25 12:47:5814499 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314500 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714501 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714502
danakj1fd259a02016-04-16 03:17:0914503 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714504
14505 // Start the first transaction to set up the SpdySession
14506 HttpRequestInfo request1;
14507 request1.method = "GET";
14508 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714509 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014510 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714511 TestCompletionCallback callback1;
14512 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014513 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314514 // This pause is a hack to avoid running into https://crbug.com/497228.
14515 data1.RunUntilPaused();
14516 base::RunLoop().RunUntilIdle();
14517 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714518
robpercival214763f2016-07-01 23:27:0114519 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714520 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14521
14522 // Now, start the HTTP request
14523 HttpRequestInfo request2;
14524 request2.method = "GET";
14525 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714526 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014527 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714528 TestCompletionCallback callback2;
14529 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014530 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514531 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714532
14533 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114534 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714535 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14536}
14537
[email protected]85f97342013-04-17 06:12:2414538// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14539// error) in SPDY session, removes the socket from pool and closes the SPDY
14540// session. Verify that new url's from the same HttpNetworkSession (and a new
14541// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114542TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314543 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414544
14545 MockRead reads1[] = {
14546 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14547 };
14548
mmenke11eb5152015-06-09 14:50:5014549 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414550
bncdf80d44fd2016-07-15 20:27:4114551 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914552 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414553 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114554 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414555 };
14556
bnc42331402016-07-25 13:36:1514557 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114558 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414559 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114560 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14561 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414562 };
14563
mmenke11eb5152015-06-09 14:50:5014564 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14565 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414566
[email protected]85f97342013-04-17 06:12:2414567 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614568 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14570 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414571
14572 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614573 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014574 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14575 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414576
danakj1fd259a02016-04-16 03:17:0914577 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014578 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414579
14580 // Start the first transaction to set up the SpdySession and verify that
14581 // connection was closed.
14582 HttpRequestInfo request1;
14583 request1.method = "GET";
14584 request1.url = GURL(https_url);
14585 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014586 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414587 TestCompletionCallback callback1;
14588 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014589 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114590 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414591
14592 // Now, start the second request and make sure it succeeds.
14593 HttpRequestInfo request2;
14594 request2.method = "GET";
14595 request2.url = GURL(https_url);
14596 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014597 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414598 TestCompletionCallback callback2;
14599 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014600 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414601
robpercival214763f2016-07-01 23:27:0114602 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414603 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14604}
14605
bncd16676a2016-07-20 16:23:0114606TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314607 ClientSocketPoolManager::set_max_sockets_per_group(
14608 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14609 ClientSocketPoolManager::set_max_sockets_per_pool(
14610 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14611
14612 // Use two different hosts with different IPs so they don't get pooled.
14613 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14614 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914615 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314616
14617 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614618 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314619 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614620 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314621 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14623
bncdf80d44fd2016-07-15 20:27:4114624 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914625 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314626 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114627 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314628 };
bnc42331402016-07-25 13:36:1514629 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114630 SpdySerializedFrame host1_resp_body(
14631 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314632 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114633 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914634 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314635 };
14636
rdsmithebb50aa2015-11-12 03:44:3814637 // Use a separate test instance for the separate SpdySession that will be
14638 // created.
bncd16676a2016-07-20 16:23:0114639 SpdyTestUtil spdy_util_2;
bnc87dcefc2017-05-25 12:47:5814640 auto spdy1_data = base::MakeUnique<SequencedSocketData>(
14641 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14642 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0314643 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14644
bncdf80d44fd2016-07-15 20:27:4114645 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914646 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314647 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114648 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314649 };
bnc42331402016-07-25 13:36:1514650 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114651 SpdySerializedFrame host2_resp_body(
14652 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314653 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114654 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914655 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314656 };
14657
bnc87dcefc2017-05-25 12:47:5814658 auto spdy2_data = base::MakeUnique<SequencedSocketData>(
14659 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14660 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0314661 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14662
14663 MockWrite http_write[] = {
14664 MockWrite("GET / HTTP/1.1\r\n"
14665 "Host: www.a.com\r\n"
14666 "Connection: keep-alive\r\n\r\n"),
14667 };
14668
14669 MockRead http_read[] = {
14670 MockRead("HTTP/1.1 200 OK\r\n"),
14671 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14672 MockRead("Content-Length: 6\r\n\r\n"),
14673 MockRead("hello!"),
14674 };
14675 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14676 http_write, arraysize(http_write));
14677 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14678
14679 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014680 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314681 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314682 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614683 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314684
14685 TestCompletionCallback callback;
14686 HttpRequestInfo request1;
14687 request1.method = "GET";
14688 request1.url = GURL("https://www.a.com/");
14689 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814690 auto trans =
14691 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314692
tfarina42834112016-09-22 13:38:2014693 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14695 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314696
14697 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214698 ASSERT_TRUE(response);
14699 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214700 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314701 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214702 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314703
14704 std::string response_data;
robpercival214763f2016-07-01 23:27:0114705 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314706 EXPECT_EQ("hello!", response_data);
14707 trans.reset();
14708 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614709 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314710
14711 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014712 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314713 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314714 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614715 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314716 HttpRequestInfo request2;
14717 request2.method = "GET";
14718 request2.url = GURL("https://www.b.com/");
14719 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814720 trans =
14721 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314722
tfarina42834112016-09-22 13:38:2014723 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14725 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314726
14727 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214728 ASSERT_TRUE(response);
14729 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214730 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314731 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214732 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114733 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314734 EXPECT_EQ("hello!", response_data);
14735 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614736 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314737 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614738 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314739
14740 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014741 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314742 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314743 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614744 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314745 HttpRequestInfo request3;
14746 request3.method = "GET";
14747 request3.url = GURL("http://www.a.com/");
14748 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814749 trans =
14750 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314751
tfarina42834112016-09-22 13:38:2014752 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14754 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314755
14756 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214757 ASSERT_TRUE(response);
14758 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314759 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14760 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214761 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114762 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314763 EXPECT_EQ("hello!", response_data);
14764 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614765 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314766 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614767 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314768}
14769
bncd16676a2016-07-20 16:23:0114770TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414771 HttpRequestInfo request;
14772 request.method = "GET";
bncce36dca22015-04-21 22:11:2314773 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414774
danakj1fd259a02016-04-16 03:17:0914775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414777
ttuttled9dbc652015-09-29 20:00:5914778 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414779 StaticSocketDataProvider data;
14780 data.set_connect_data(mock_connect);
14781 session_deps_.socket_factory->AddSocketDataProvider(&data);
14782
14783 TestCompletionCallback callback;
14784
tfarina42834112016-09-22 13:38:2014785 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414787
14788 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114789 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414790
[email protected]79e1fd62013-06-20 06:50:0414791 // We don't care whether this succeeds or fails, but it shouldn't crash.
14792 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614793 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714794
14795 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614796 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714797 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114798 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914799
14800 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614801 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914802 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414803}
14804
bncd16676a2016-07-20 16:23:0114805TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414806 HttpRequestInfo request;
14807 request.method = "GET";
bncce36dca22015-04-21 22:11:2314808 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414809
danakj1fd259a02016-04-16 03:17:0914810 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414812
ttuttled9dbc652015-09-29 20:00:5914813 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414814 StaticSocketDataProvider data;
14815 data.set_connect_data(mock_connect);
14816 session_deps_.socket_factory->AddSocketDataProvider(&data);
14817
14818 TestCompletionCallback callback;
14819
tfarina42834112016-09-22 13:38:2014820 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414822
14823 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114824 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414825
[email protected]79e1fd62013-06-20 06:50:0414826 // We don't care whether this succeeds or fails, but it shouldn't crash.
14827 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614828 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714829
14830 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614831 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714832 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114833 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914834
14835 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614836 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914837 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414838}
14839
bncd16676a2016-07-20 16:23:0114840TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414841 HttpRequestInfo request;
14842 request.method = "GET";
bncce36dca22015-04-21 22:11:2314843 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414844
danakj1fd259a02016-04-16 03:17:0914845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614846 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414847
14848 MockWrite data_writes[] = {
14849 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14850 };
14851 MockRead data_reads[] = {
14852 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14853 };
14854
14855 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14856 data_writes, arraysize(data_writes));
14857 session_deps_.socket_factory->AddSocketDataProvider(&data);
14858
14859 TestCompletionCallback callback;
14860
tfarina42834112016-09-22 13:38:2014861 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114862 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414863
14864 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114865 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414866
[email protected]79e1fd62013-06-20 06:50:0414867 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614868 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414869 EXPECT_TRUE(request_headers.HasHeader("Host"));
14870}
14871
bncd16676a2016-07-20 16:23:0114872TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414873 HttpRequestInfo request;
14874 request.method = "GET";
bncce36dca22015-04-21 22:11:2314875 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414876
danakj1fd259a02016-04-16 03:17:0914877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414879
14880 MockWrite data_writes[] = {
14881 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14882 };
14883 MockRead data_reads[] = {
14884 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14885 };
14886
14887 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14888 data_writes, arraysize(data_writes));
14889 session_deps_.socket_factory->AddSocketDataProvider(&data);
14890
14891 TestCompletionCallback callback;
14892
tfarina42834112016-09-22 13:38:2014893 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414895
14896 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114897 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414898
[email protected]79e1fd62013-06-20 06:50:0414899 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614900 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414901 EXPECT_TRUE(request_headers.HasHeader("Host"));
14902}
14903
bncd16676a2016-07-20 16:23:0114904TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414905 HttpRequestInfo request;
14906 request.method = "GET";
bncce36dca22015-04-21 22:11:2314907 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414908
danakj1fd259a02016-04-16 03:17:0914909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614910 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414911
14912 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314913 MockWrite(
14914 "GET / HTTP/1.1\r\n"
14915 "Host: www.example.org\r\n"
14916 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414917 };
14918 MockRead data_reads[] = {
14919 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14920 };
14921
14922 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14923 data_writes, arraysize(data_writes));
14924 session_deps_.socket_factory->AddSocketDataProvider(&data);
14925
14926 TestCompletionCallback callback;
14927
tfarina42834112016-09-22 13:38:2014928 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414930
14931 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114932 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414933
[email protected]79e1fd62013-06-20 06:50:0414934 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614935 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414936 EXPECT_TRUE(request_headers.HasHeader("Host"));
14937}
14938
bncd16676a2016-07-20 16:23:0114939TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414940 HttpRequestInfo request;
14941 request.method = "GET";
bncce36dca22015-04-21 22:11:2314942 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414943
danakj1fd259a02016-04-16 03:17:0914944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414946
14947 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314948 MockWrite(
14949 "GET / HTTP/1.1\r\n"
14950 "Host: www.example.org\r\n"
14951 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414952 };
14953 MockRead data_reads[] = {
14954 MockRead(ASYNC, ERR_CONNECTION_RESET),
14955 };
14956
14957 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14958 data_writes, arraysize(data_writes));
14959 session_deps_.socket_factory->AddSocketDataProvider(&data);
14960
14961 TestCompletionCallback callback;
14962
tfarina42834112016-09-22 13:38:2014963 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414965
14966 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114967 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414968
[email protected]79e1fd62013-06-20 06:50:0414969 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614970 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414971 EXPECT_TRUE(request_headers.HasHeader("Host"));
14972}
14973
bncd16676a2016-07-20 16:23:0114974TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414975 HttpRequestInfo request;
14976 request.method = "GET";
bncce36dca22015-04-21 22:11:2314977 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414978 request.extra_headers.SetHeader("X-Foo", "bar");
14979
danakj1fd259a02016-04-16 03:17:0914980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414982
14983 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314984 MockWrite(
14985 "GET / HTTP/1.1\r\n"
14986 "Host: www.example.org\r\n"
14987 "Connection: keep-alive\r\n"
14988 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414989 };
14990 MockRead data_reads[] = {
14991 MockRead("HTTP/1.1 200 OK\r\n"
14992 "Content-Length: 5\r\n\r\n"
14993 "hello"),
14994 MockRead(ASYNC, ERR_UNEXPECTED),
14995 };
14996
14997 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14998 data_writes, arraysize(data_writes));
14999 session_deps_.socket_factory->AddSocketDataProvider(&data);
15000
15001 TestCompletionCallback callback;
15002
tfarina42834112016-09-22 13:38:2015003 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415005
15006 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115007 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415008
15009 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615010 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415011 std::string foo;
15012 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15013 EXPECT_EQ("bar", foo);
15014}
15015
[email protected]bf828982013-08-14 18:01:4715016namespace {
15017
yhiranoa7e05bb2014-11-06 05:40:3915018// Fake HttpStream that simply records calls to SetPriority().
15019class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315020 public base::SupportsWeakPtr<FakeStream> {
15021 public:
15022 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015023 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315024
15025 RequestPriority priority() const { return priority_; }
15026
dchengb03027d2014-10-21 12:00:2015027 int InitializeStream(const HttpRequestInfo* request_info,
15028 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015029 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015030 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315031 return ERR_IO_PENDING;
15032 }
15033
dchengb03027d2014-10-21 12:00:2015034 int SendRequest(const HttpRequestHeaders& request_headers,
15035 HttpResponseInfo* response,
15036 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315037 ADD_FAILURE();
15038 return ERR_UNEXPECTED;
15039 }
15040
dchengb03027d2014-10-21 12:00:2015041 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315042 ADD_FAILURE();
15043 return ERR_UNEXPECTED;
15044 }
15045
dchengb03027d2014-10-21 12:00:2015046 int ReadResponseBody(IOBuffer* buf,
15047 int buf_len,
15048 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315049 ADD_FAILURE();
15050 return ERR_UNEXPECTED;
15051 }
15052
dchengb03027d2014-10-21 12:00:2015053 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315054
dchengb03027d2014-10-21 12:00:2015055 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315056 ADD_FAILURE();
15057 return false;
15058 }
15059
dchengb03027d2014-10-21 12:00:2015060 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315061 ADD_FAILURE();
15062 return false;
15063 }
15064
dchengb03027d2014-10-21 12:00:2015065 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315066
mmenkebd84c392015-09-02 14:12:3415067 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315068
sclittle4de1bab92015-09-22 21:28:2415069 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915070 ADD_FAILURE();
15071 return 0;
15072 }
15073
sclittlebe1ccf62015-09-02 19:40:3615074 int64_t GetTotalSentBytes() const override {
15075 ADD_FAILURE();
15076 return 0;
15077 }
15078
dchengb03027d2014-10-21 12:00:2015079 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315080 ADD_FAILURE();
15081 return false;
15082 }
15083
rchcd379012017-04-12 21:53:3215084 bool GetAlternativeService(
15085 AlternativeService* alternative_service) const override {
15086 ADD_FAILURE();
15087 return false;
15088 }
15089
dchengb03027d2014-10-21 12:00:2015090 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15091
15092 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315093 ADD_FAILURE();
15094 }
15095
ttuttled9dbc652015-09-29 20:00:5915096 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15097
nharper78e6d2b2016-09-21 05:42:3515098 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15099 TokenBindingType tb_type,
15100 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415101 ADD_FAILURE();
15102 return ERR_NOT_IMPLEMENTED;
15103 }
15104
dchengb03027d2014-10-21 12:00:2015105 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315106
zhongyica364fbb2015-12-12 03:39:1215107 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15108
dchengb03027d2014-10-21 12:00:2015109 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315110
yhiranoa7e05bb2014-11-06 05:40:3915111 HttpStream* RenewStreamForAuth() override { return NULL; }
15112
[email protected]e86839fd2013-08-14 18:29:0315113 private:
15114 RequestPriority priority_;
15115
15116 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15117};
15118
15119// Fake HttpStreamRequest that simply records calls to SetPriority()
15120// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715121class FakeStreamRequest : public HttpStreamRequest,
15122 public base::SupportsWeakPtr<FakeStreamRequest> {
15123 public:
[email protected]e86839fd2013-08-14 18:29:0315124 FakeStreamRequest(RequestPriority priority,
15125 HttpStreamRequest::Delegate* delegate)
15126 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415127 delegate_(delegate),
15128 websocket_stream_create_helper_(NULL) {}
15129
15130 FakeStreamRequest(RequestPriority priority,
15131 HttpStreamRequest::Delegate* delegate,
15132 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15133 : priority_(priority),
15134 delegate_(delegate),
15135 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315136
dchengb03027d2014-10-21 12:00:2015137 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715138
15139 RequestPriority priority() const { return priority_; }
15140
[email protected]831e4a32013-11-14 02:14:4415141 const WebSocketHandshakeStreamBase::CreateHelper*
15142 websocket_stream_create_helper() const {
15143 return websocket_stream_create_helper_;
15144 }
15145
[email protected]e86839fd2013-08-14 18:29:0315146 // Create a new FakeStream and pass it to the request's
15147 // delegate. Returns a weak pointer to the FakeStream.
15148 base::WeakPtr<FakeStream> FinishStreamRequest() {
bnc5029f4632017-06-08 16:19:0015149 auto fake_stream = base::MakeUnique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315150 // Do this before calling OnStreamReady() as OnStreamReady() may
15151 // immediately delete |fake_stream|.
15152 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015153 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315154 return weak_stream;
15155 }
15156
asanka681f02d2017-02-22 17:06:3915157 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715158 ADD_FAILURE();
15159 return ERR_UNEXPECTED;
15160 }
15161
dchengb03027d2014-10-21 12:00:2015162 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715163 ADD_FAILURE();
15164 return LoadState();
15165 }
15166
dchengb03027d2014-10-21 12:00:2015167 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715168
bnc94c92842016-09-21 15:22:5215169 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715170
bnc6227b26e2016-08-12 02:00:4315171 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715172
dchengb03027d2014-10-21 12:00:2015173 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715174
ttuttle1f2d7e92015-04-28 16:17:4715175 const ConnectionAttempts& connection_attempts() const override {
15176 static ConnectionAttempts no_attempts;
15177 return no_attempts;
15178 }
15179
[email protected]bf828982013-08-14 18:01:4715180 private:
15181 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315182 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415183 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715184
15185 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15186};
15187
15188// Fake HttpStreamFactory that vends FakeStreamRequests.
15189class FakeStreamFactory : public HttpStreamFactory {
15190 public:
15191 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015192 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715193
15194 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15195 // RequestStream() (which may be NULL if it was destroyed already).
15196 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15197 return last_stream_request_;
15198 }
15199
xunjieli96f2a402017-06-05 17:24:2715200 std::unique_ptr<HttpStreamRequest> RequestStream(
15201 const HttpRequestInfo& info,
15202 RequestPriority priority,
15203 const SSLConfig& server_ssl_config,
15204 const SSLConfig& proxy_ssl_config,
15205 HttpStreamRequest::Delegate* delegate,
15206 bool enable_ip_based_pooling,
15207 bool enable_alternative_services,
15208 const NetLogWithSource& net_log) override {
15209 auto fake_request = base::MakeUnique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715210 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715211 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715212 }
15213
xunjieli96f2a402017-06-05 17:24:2715214 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815215 const HttpRequestInfo& info,
15216 RequestPriority priority,
15217 const SSLConfig& server_ssl_config,
15218 const SSLConfig& proxy_ssl_config,
15219 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915220 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615221 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015222 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815223 NOTREACHED();
15224 return nullptr;
15225 }
15226
xunjieli96f2a402017-06-05 17:24:2715227 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715228 const HttpRequestInfo& info,
15229 RequestPriority priority,
15230 const SSLConfig& server_ssl_config,
15231 const SSLConfig& proxy_ssl_config,
15232 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615233 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915234 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615235 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015236 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715237 auto fake_request =
15238 base::MakeUnique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415239 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715240 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715241 }
15242
dchengb03027d2014-10-21 12:00:2015243 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915244 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715245 ADD_FAILURE();
15246 }
15247
dchengb03027d2014-10-21 12:00:2015248 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715249 ADD_FAILURE();
15250 return NULL;
15251 }
15252
xunjielif5267de2017-01-20 21:18:5715253 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15254 const std::string& parent_absolute_name) const override {
15255 ADD_FAILURE();
15256 }
15257
[email protected]bf828982013-08-14 18:01:4715258 private:
15259 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15260
15261 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15262};
15263
Adam Rice425cf122015-01-19 06:18:2415264// TODO(ricea): Maybe unify this with the one in
15265// url_request_http_job_unittest.cc ?
15266class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15267 public:
danakj1fd259a02016-04-16 03:17:0915268 FakeWebSocketBasicHandshakeStream(
15269 std::unique_ptr<ClientSocketHandle> connection,
15270 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215271 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415272
15273 // Fake implementation of HttpStreamBase methods.
15274 // This ends up being quite "real" because this object has to really send data
15275 // on the mock socket. It might be easier to use the real implementation, but
15276 // the fact that the WebSocket code is not compiled on iOS makes that
15277 // difficult.
15278 int InitializeStream(const HttpRequestInfo* request_info,
15279 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015280 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415281 const CompletionCallback& callback) override {
15282 state_.Initialize(request_info, priority, net_log, callback);
15283 return OK;
15284 }
15285
15286 int SendRequest(const HttpRequestHeaders& request_headers,
15287 HttpResponseInfo* response,
15288 const CompletionCallback& callback) override {
15289 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15290 response, callback);
15291 }
15292
15293 int ReadResponseHeaders(const CompletionCallback& callback) override {
15294 return parser()->ReadResponseHeaders(callback);
15295 }
15296
15297 int ReadResponseBody(IOBuffer* buf,
15298 int buf_len,
15299 const CompletionCallback& callback) override {
15300 NOTREACHED();
15301 return ERR_IO_PENDING;
15302 }
15303
15304 void Close(bool not_reusable) override {
15305 if (parser())
15306 parser()->Close(true);
15307 }
15308
15309 bool IsResponseBodyComplete() const override {
15310 NOTREACHED();
15311 return false;
15312 }
15313
Adam Rice425cf122015-01-19 06:18:2415314 bool IsConnectionReused() const override {
15315 NOTREACHED();
15316 return false;
15317 }
15318 void SetConnectionReused() override { NOTREACHED(); }
15319
mmenkebd84c392015-09-02 14:12:3415320 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415321
sclittle4de1bab92015-09-22 21:28:2415322 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415323 NOTREACHED();
15324 return 0;
15325 }
15326
sclittlebe1ccf62015-09-02 19:40:3615327 int64_t GetTotalSentBytes() const override {
15328 NOTREACHED();
15329 return 0;
15330 }
15331
Adam Rice425cf122015-01-19 06:18:2415332 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15333 NOTREACHED();
15334 return false;
15335 }
15336
rchcd379012017-04-12 21:53:3215337 bool GetAlternativeService(
15338 AlternativeService* alternative_service) const override {
15339 ADD_FAILURE();
15340 return false;
15341 }
15342
Adam Ricecb76ac62015-02-20 05:33:2515343 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415344
15345 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15346 NOTREACHED();
15347 }
15348
ttuttled9dbc652015-09-29 20:00:5915349 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15350
nharper78e6d2b2016-09-21 05:42:3515351 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15352 TokenBindingType tb_type,
15353 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415354 ADD_FAILURE();
15355 return ERR_NOT_IMPLEMENTED;
15356 }
15357
Adam Rice425cf122015-01-19 06:18:2415358 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15359
zhongyica364fbb2015-12-12 03:39:1215360 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15361
Adam Rice425cf122015-01-19 06:18:2415362 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15363
Adam Rice425cf122015-01-19 06:18:2415364 HttpStream* RenewStreamForAuth() override {
15365 NOTREACHED();
15366 return nullptr;
15367 }
15368
15369 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915370 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415371 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915372 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415373 }
15374
15375 private:
15376 HttpStreamParser* parser() const { return state_.parser(); }
15377 HttpBasicState state_;
15378
15379 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15380};
15381
[email protected]831e4a32013-11-14 02:14:4415382// TODO(yhirano): Split this class out into a net/websockets file, if it is
15383// worth doing.
15384class FakeWebSocketStreamCreateHelper :
15385 public WebSocketHandshakeStreamBase::CreateHelper {
15386 public:
bnc615cf2f2017-05-19 18:53:2615387 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915388 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315389 bool using_proxy) override {
bnc615cf2f2017-05-19 18:53:2615390 return base::MakeUnique<FakeWebSocketBasicHandshakeStream>(
15391 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415392 }
15393
dchengb03027d2014-10-21 12:00:2015394 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415395
danakj1fd259a02016-04-16 03:17:0915396 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415397 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915398 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415399 }
15400};
15401
[email protected]bf828982013-08-14 18:01:4715402} // namespace
15403
15404// Make sure that HttpNetworkTransaction passes on its priority to its
15405// stream request on start.
bncd16676a2016-07-20 16:23:0115406TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915407 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215408 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715409 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915410 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715411
krasinc06a72a2016-12-21 03:42:4615412 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115413 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715414
wezca1070932016-05-26 20:30:5215415 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715416
[email protected]bf828982013-08-14 18:01:4715417 TestCompletionCallback callback;
15418 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015419 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715420
15421 base::WeakPtr<FakeStreamRequest> fake_request =
15422 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215423 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715424 EXPECT_EQ(LOW, fake_request->priority());
15425}
15426
15427// Make sure that HttpNetworkTransaction passes on its priority
15428// updates to its stream request.
bncd16676a2016-07-20 16:23:0115429TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215431 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715432 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915433 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715434
krasinc06a72a2016-12-21 03:42:4615435 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115436 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715437
[email protected]bf828982013-08-14 18:01:4715438 TestCompletionCallback callback;
15439 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015440 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715441
15442 base::WeakPtr<FakeStreamRequest> fake_request =
15443 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215444 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715445 EXPECT_EQ(LOW, fake_request->priority());
15446
15447 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215448 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715449 EXPECT_EQ(LOWEST, fake_request->priority());
15450}
15451
[email protected]e86839fd2013-08-14 18:29:0315452// Make sure that HttpNetworkTransaction passes on its priority
15453// updates to its stream.
bncd16676a2016-07-20 16:23:0115454TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215456 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315457 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915458 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315459
krasinc06a72a2016-12-21 03:42:4615460 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115461 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315462
[email protected]e86839fd2013-08-14 18:29:0315463 TestCompletionCallback callback;
15464 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015465 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315466
15467 base::WeakPtr<FakeStreamRequest> fake_request =
15468 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215469 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315470 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215471 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315472 EXPECT_EQ(LOW, fake_stream->priority());
15473
15474 trans.SetPriority(LOWEST);
15475 EXPECT_EQ(LOWEST, fake_stream->priority());
15476}
15477
bncd16676a2016-07-20 16:23:0115478TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415479 // The same logic needs to be tested for both ws: and wss: schemes, but this
15480 // test is already parameterised on NextProto, so it uses a loop to verify
15481 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315482 std::string test_cases[] = {"ws://www.example.org/",
15483 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415484 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215486 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415487 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15488 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315489 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915490 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415491
krasinc06a72a2016-12-21 03:42:4615492 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115493 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415494 trans.SetWebSocketHandshakeStreamCreateHelper(
15495 &websocket_stream_create_helper);
15496
[email protected]831e4a32013-11-14 02:14:4415497 TestCompletionCallback callback;
15498 request.method = "GET";
15499 request.url = GURL(test_cases[i]);
15500
15501 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015502 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415503
15504 base::WeakPtr<FakeStreamRequest> fake_request =
15505 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215506 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415507 EXPECT_EQ(&websocket_stream_create_helper,
15508 fake_request->websocket_stream_create_helper());
15509 }
15510}
15511
[email protected]043b68c82013-08-22 23:41:5215512// Tests that when a used socket is returned to the SSL socket pool, it's closed
15513// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115514TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215515 ClientSocketPoolManager::set_max_sockets_per_group(
15516 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15517 ClientSocketPoolManager::set_max_sockets_per_pool(
15518 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15519
15520 // Set up SSL request.
15521
15522 HttpRequestInfo ssl_request;
15523 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315524 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215525
15526 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315527 MockWrite(
15528 "GET / HTTP/1.1\r\n"
15529 "Host: www.example.org\r\n"
15530 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215531 };
15532 MockRead ssl_reads[] = {
15533 MockRead("HTTP/1.1 200 OK\r\n"),
15534 MockRead("Content-Length: 11\r\n\r\n"),
15535 MockRead("hello world"),
15536 MockRead(SYNCHRONOUS, OK),
15537 };
15538 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15539 ssl_writes, arraysize(ssl_writes));
15540 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15541
15542 SSLSocketDataProvider ssl(ASYNC, OK);
15543 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15544
15545 // Set up HTTP request.
15546
15547 HttpRequestInfo http_request;
15548 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315549 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215550
15551 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315552 MockWrite(
15553 "GET / HTTP/1.1\r\n"
15554 "Host: www.example.org\r\n"
15555 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215556 };
15557 MockRead http_reads[] = {
15558 MockRead("HTTP/1.1 200 OK\r\n"),
15559 MockRead("Content-Length: 7\r\n\r\n"),
15560 MockRead("falafel"),
15561 MockRead(SYNCHRONOUS, OK),
15562 };
15563 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15564 http_writes, arraysize(http_writes));
15565 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15566
danakj1fd259a02016-04-16 03:17:0915567 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215568
15569 // Start the SSL request.
15570 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615571 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015572 ASSERT_EQ(ERR_IO_PENDING,
15573 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15574 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215575
15576 // Start the HTTP request. Pool should stall.
15577 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615578 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015579 ASSERT_EQ(ERR_IO_PENDING,
15580 http_trans.Start(&http_request, http_callback.callback(),
15581 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115582 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215583
15584 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115585 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215586 std::string response_data;
bnc691fda62016-08-12 00:43:1615587 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215588 EXPECT_EQ("hello world", response_data);
15589
15590 // The SSL socket should automatically be closed, so the HTTP request can
15591 // start.
dcheng48459ac22014-08-26 00:46:4115592 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15593 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215594
15595 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115596 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615597 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215598 EXPECT_EQ("falafel", response_data);
15599
dcheng48459ac22014-08-26 00:46:4115600 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215601}
15602
15603// Tests that when a SSL connection is established but there's no corresponding
15604// request that needs it, the new socket is closed if the transport socket pool
15605// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115606TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215607 ClientSocketPoolManager::set_max_sockets_per_group(
15608 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15609 ClientSocketPoolManager::set_max_sockets_per_pool(
15610 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15611
15612 // Set up an ssl request.
15613
15614 HttpRequestInfo ssl_request;
15615 ssl_request.method = "GET";
15616 ssl_request.url = GURL("https://www.foopy.com/");
15617
15618 // No data will be sent on the SSL socket.
15619 StaticSocketDataProvider ssl_data;
15620 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15621
15622 SSLSocketDataProvider ssl(ASYNC, OK);
15623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15624
15625 // Set up HTTP request.
15626
15627 HttpRequestInfo http_request;
15628 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315629 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215630
15631 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315632 MockWrite(
15633 "GET / HTTP/1.1\r\n"
15634 "Host: www.example.org\r\n"
15635 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215636 };
15637 MockRead http_reads[] = {
15638 MockRead("HTTP/1.1 200 OK\r\n"),
15639 MockRead("Content-Length: 7\r\n\r\n"),
15640 MockRead("falafel"),
15641 MockRead(SYNCHRONOUS, OK),
15642 };
15643 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15644 http_writes, arraysize(http_writes));
15645 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15646
danakj1fd259a02016-04-16 03:17:0915647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215648
15649 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15650 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915651 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915652 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115653 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215654
15655 // Start the HTTP request. Pool should stall.
15656 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615657 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015658 ASSERT_EQ(ERR_IO_PENDING,
15659 http_trans.Start(&http_request, http_callback.callback(),
15660 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115661 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215662
15663 // The SSL connection will automatically be closed once the connection is
15664 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115665 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215666 std::string response_data;
bnc691fda62016-08-12 00:43:1615667 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215668 EXPECT_EQ("falafel", response_data);
15669
dcheng48459ac22014-08-26 00:46:4115670 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215671}
15672
bncd16676a2016-07-20 16:23:0115673TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915674 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215675 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715676 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215677 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415678
15679 HttpRequestInfo request;
15680 request.method = "POST";
15681 request.url = GURL("http://www.foo.com/");
15682 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415683
danakj1fd259a02016-04-16 03:17:0915684 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415686 // Send headers successfully, but get an error while sending the body.
15687 MockWrite data_writes[] = {
15688 MockWrite("POST / HTTP/1.1\r\n"
15689 "Host: www.foo.com\r\n"
15690 "Connection: keep-alive\r\n"
15691 "Content-Length: 3\r\n\r\n"),
15692 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15693 };
15694
15695 MockRead data_reads[] = {
15696 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15697 MockRead("hello world"),
15698 MockRead(SYNCHRONOUS, OK),
15699 };
15700 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15701 arraysize(data_writes));
15702 session_deps_.socket_factory->AddSocketDataProvider(&data);
15703
15704 TestCompletionCallback callback;
15705
tfarina42834112016-09-22 13:38:2015706 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415708
15709 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115710 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415711
bnc691fda62016-08-12 00:43:1615712 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215713 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415714
wezca1070932016-05-26 20:30:5215715 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415716 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15717
15718 std::string response_data;
bnc691fda62016-08-12 00:43:1615719 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115720 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415721 EXPECT_EQ("hello world", response_data);
15722}
15723
15724// This test makes sure the retry logic doesn't trigger when reading an error
15725// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115726TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415727 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415729 MockWrite data_writes[] = {
15730 MockWrite("GET / HTTP/1.1\r\n"
15731 "Host: www.foo.com\r\n"
15732 "Connection: keep-alive\r\n\r\n"),
15733 MockWrite("POST / HTTP/1.1\r\n"
15734 "Host: www.foo.com\r\n"
15735 "Connection: keep-alive\r\n"
15736 "Content-Length: 3\r\n\r\n"),
15737 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15738 };
15739
15740 MockRead data_reads[] = {
15741 MockRead("HTTP/1.1 200 Peachy\r\n"
15742 "Content-Length: 14\r\n\r\n"),
15743 MockRead("first response"),
15744 MockRead("HTTP/1.1 400 Not OK\r\n"
15745 "Content-Length: 15\r\n\r\n"),
15746 MockRead("second response"),
15747 MockRead(SYNCHRONOUS, OK),
15748 };
15749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15750 arraysize(data_writes));
15751 session_deps_.socket_factory->AddSocketDataProvider(&data);
15752
15753 TestCompletionCallback callback;
15754 HttpRequestInfo request1;
15755 request1.method = "GET";
15756 request1.url = GURL("http://www.foo.com/");
15757 request1.load_flags = 0;
15758
bnc87dcefc2017-05-25 12:47:5815759 auto trans1 =
15760 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015761 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415763
15764 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115765 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415766
15767 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215768 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415769
wezca1070932016-05-26 20:30:5215770 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415771 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15772
15773 std::string response_data1;
15774 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115775 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415776 EXPECT_EQ("first response", response_data1);
15777 // Delete the transaction to release the socket back into the socket pool.
15778 trans1.reset();
15779
danakj1fd259a02016-04-16 03:17:0915780 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215781 element_readers.push_back(
bnc87dcefc2017-05-25 12:47:5815782 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215783 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415784
15785 HttpRequestInfo request2;
15786 request2.method = "POST";
15787 request2.url = GURL("http://www.foo.com/");
15788 request2.upload_data_stream = &upload_data_stream;
15789 request2.load_flags = 0;
15790
bnc691fda62016-08-12 00:43:1615791 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015792 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415794
15795 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115796 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415797
bnc691fda62016-08-12 00:43:1615798 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215799 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415800
wezca1070932016-05-26 20:30:5215801 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415802 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15803
15804 std::string response_data2;
bnc691fda62016-08-12 00:43:1615805 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115806 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415807 EXPECT_EQ("second response", response_data2);
15808}
15809
bncd16676a2016-07-20 16:23:0115810TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415811 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915812 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215813 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715814 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215815 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415816
15817 HttpRequestInfo request;
15818 request.method = "POST";
15819 request.url = GURL("http://www.foo.com/");
15820 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415821
danakj1fd259a02016-04-16 03:17:0915822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415824 // Send headers successfully, but get an error while sending the body.
15825 MockWrite data_writes[] = {
15826 MockWrite("POST / HTTP/1.1\r\n"
15827 "Host: www.foo.com\r\n"
15828 "Connection: keep-alive\r\n"
15829 "Content-Length: 3\r\n\r\n"
15830 "fo"),
15831 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15832 };
15833
15834 MockRead data_reads[] = {
15835 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15836 MockRead("hello world"),
15837 MockRead(SYNCHRONOUS, OK),
15838 };
15839 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15840 arraysize(data_writes));
15841 session_deps_.socket_factory->AddSocketDataProvider(&data);
15842
15843 TestCompletionCallback callback;
15844
tfarina42834112016-09-22 13:38:2015845 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415847
15848 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115849 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415850
bnc691fda62016-08-12 00:43:1615851 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215852 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415853
wezca1070932016-05-26 20:30:5215854 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415855 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15856
15857 std::string response_data;
bnc691fda62016-08-12 00:43:1615858 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115859 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415860 EXPECT_EQ("hello world", response_data);
15861}
15862
15863// This tests the more common case than the previous test, where headers and
15864// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115865TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715866 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415867
15868 HttpRequestInfo request;
15869 request.method = "POST";
15870 request.url = GURL("http://www.foo.com/");
15871 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415872
danakj1fd259a02016-04-16 03:17:0915873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415875 // Send headers successfully, but get an error while sending the body.
15876 MockWrite data_writes[] = {
15877 MockWrite("POST / HTTP/1.1\r\n"
15878 "Host: www.foo.com\r\n"
15879 "Connection: keep-alive\r\n"
15880 "Transfer-Encoding: chunked\r\n\r\n"),
15881 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15882 };
15883
15884 MockRead data_reads[] = {
15885 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15886 MockRead("hello world"),
15887 MockRead(SYNCHRONOUS, OK),
15888 };
15889 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15890 arraysize(data_writes));
15891 session_deps_.socket_factory->AddSocketDataProvider(&data);
15892
15893 TestCompletionCallback callback;
15894
tfarina42834112016-09-22 13:38:2015895 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415897 // Make sure the headers are sent before adding a chunk. This ensures that
15898 // they can't be merged with the body in a single send. Not currently
15899 // necessary since a chunked body is never merged with headers, but this makes
15900 // the test more future proof.
15901 base::RunLoop().RunUntilIdle();
15902
mmenkecbc2b712014-10-09 20:29:0715903 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415904
15905 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115906 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415907
bnc691fda62016-08-12 00:43:1615908 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215909 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415910
wezca1070932016-05-26 20:30:5215911 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415912 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15913
15914 std::string response_data;
bnc691fda62016-08-12 00:43:1615915 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115916 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415917 EXPECT_EQ("hello world", response_data);
15918}
15919
bncd16676a2016-07-20 16:23:0115920TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915921 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215922 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715923 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215924 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415925
15926 HttpRequestInfo request;
15927 request.method = "POST";
15928 request.url = GURL("http://www.foo.com/");
15929 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415930
danakj1fd259a02016-04-16 03:17:0915931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615932 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415933
15934 MockWrite data_writes[] = {
15935 MockWrite("POST / HTTP/1.1\r\n"
15936 "Host: www.foo.com\r\n"
15937 "Connection: keep-alive\r\n"
15938 "Content-Length: 3\r\n\r\n"),
15939 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15940 };
15941
15942 MockRead data_reads[] = {
15943 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15944 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15945 MockRead("hello world"),
15946 MockRead(SYNCHRONOUS, OK),
15947 };
15948 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15949 arraysize(data_writes));
15950 session_deps_.socket_factory->AddSocketDataProvider(&data);
15951
15952 TestCompletionCallback callback;
15953
tfarina42834112016-09-22 13:38:2015954 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415956
15957 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115958 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415959
bnc691fda62016-08-12 00:43:1615960 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215961 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415962
wezca1070932016-05-26 20:30:5215963 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415964 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15965
15966 std::string response_data;
bnc691fda62016-08-12 00:43:1615967 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115968 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415969 EXPECT_EQ("hello world", response_data);
15970}
15971
bncd16676a2016-07-20 16:23:0115972TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915973 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215974 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715975 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215976 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415977
15978 HttpRequestInfo request;
15979 request.method = "POST";
15980 request.url = GURL("http://www.foo.com/");
15981 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415982
danakj1fd259a02016-04-16 03:17:0915983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615984 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415985 // Send headers successfully, but get an error while sending the body.
15986 MockWrite data_writes[] = {
15987 MockWrite("POST / HTTP/1.1\r\n"
15988 "Host: www.foo.com\r\n"
15989 "Connection: keep-alive\r\n"
15990 "Content-Length: 3\r\n\r\n"),
15991 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15992 };
15993
15994 MockRead data_reads[] = {
15995 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15996 MockRead("hello world"),
15997 MockRead(SYNCHRONOUS, OK),
15998 };
15999 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16000 arraysize(data_writes));
16001 session_deps_.socket_factory->AddSocketDataProvider(&data);
16002
16003 TestCompletionCallback callback;
16004
tfarina42834112016-09-22 13:38:2016005 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416007
16008 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116009 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416010}
16011
bncd16676a2016-07-20 16:23:0116012TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416013 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916014 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216015 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716016 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216017 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416018
16019 HttpRequestInfo request;
16020 request.method = "POST";
16021 request.url = GURL("http://www.foo.com/");
16022 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416023
danakj1fd259a02016-04-16 03:17:0916024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616025 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416026 // Send headers successfully, but get an error while sending the body.
16027 MockWrite data_writes[] = {
16028 MockWrite("POST / HTTP/1.1\r\n"
16029 "Host: www.foo.com\r\n"
16030 "Connection: keep-alive\r\n"
16031 "Content-Length: 3\r\n\r\n"),
16032 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16033 };
16034
16035 MockRead data_reads[] = {
16036 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16037 MockRead("HTTP/1.0 302 Redirect\r\n"),
16038 MockRead("Location: http://somewhere-else.com/\r\n"),
16039 MockRead("Content-Length: 0\r\n\r\n"),
16040 MockRead(SYNCHRONOUS, OK),
16041 };
16042 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16043 arraysize(data_writes));
16044 session_deps_.socket_factory->AddSocketDataProvider(&data);
16045
16046 TestCompletionCallback callback;
16047
tfarina42834112016-09-22 13:38:2016048 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416050
16051 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116052 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416053}
16054
bncd16676a2016-07-20 16:23:0116055TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916056 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216057 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716058 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216059 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416060
16061 HttpRequestInfo request;
16062 request.method = "POST";
16063 request.url = GURL("http://www.foo.com/");
16064 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416065
danakj1fd259a02016-04-16 03:17:0916066 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616067 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416068 // Send headers successfully, but get an error while sending the body.
16069 MockWrite data_writes[] = {
16070 MockWrite("POST / HTTP/1.1\r\n"
16071 "Host: www.foo.com\r\n"
16072 "Connection: keep-alive\r\n"
16073 "Content-Length: 3\r\n\r\n"),
16074 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16075 };
16076
16077 MockRead data_reads[] = {
16078 MockRead("HTTP 0.9 rocks!"),
16079 MockRead(SYNCHRONOUS, OK),
16080 };
16081 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16082 arraysize(data_writes));
16083 session_deps_.socket_factory->AddSocketDataProvider(&data);
16084
16085 TestCompletionCallback callback;
16086
tfarina42834112016-09-22 13:38:2016087 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416089
16090 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116091 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416092}
16093
bncd16676a2016-07-20 16:23:0116094TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916095 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216096 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716097 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216098 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416099
16100 HttpRequestInfo request;
16101 request.method = "POST";
16102 request.url = GURL("http://www.foo.com/");
16103 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416104
danakj1fd259a02016-04-16 03:17:0916105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616106 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416107 // Send headers successfully, but get an error while sending the body.
16108 MockWrite data_writes[] = {
16109 MockWrite("POST / HTTP/1.1\r\n"
16110 "Host: www.foo.com\r\n"
16111 "Connection: keep-alive\r\n"
16112 "Content-Length: 3\r\n\r\n"),
16113 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16114 };
16115
16116 MockRead data_reads[] = {
16117 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16118 MockRead(SYNCHRONOUS, OK),
16119 };
16120 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16121 arraysize(data_writes));
16122 session_deps_.socket_factory->AddSocketDataProvider(&data);
16123
16124 TestCompletionCallback callback;
16125
tfarina42834112016-09-22 13:38:2016126 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416128
16129 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116130 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416131}
16132
Adam Rice425cf122015-01-19 06:18:2416133// Verify that proxy headers are not sent to the destination server when
16134// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116135TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416136 HttpRequestInfo request;
16137 request.method = "GET";
bncce36dca22015-04-21 22:11:2316138 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416139 AddWebSocketHeaders(&request.extra_headers);
16140
16141 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316142 session_deps_.proxy_service =
16143 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416144
danakj1fd259a02016-04-16 03:17:0916145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416146
16147 // Since a proxy is configured, try to establish a tunnel.
16148 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716149 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16150 "Host: www.example.org:443\r\n"
16151 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416152
16153 // After calling trans->RestartWithAuth(), this is the request we should
16154 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716155 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16156 "Host: www.example.org:443\r\n"
16157 "Proxy-Connection: keep-alive\r\n"
16158 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416159
rsleevidb16bb02015-11-12 23:47:1716160 MockWrite("GET / HTTP/1.1\r\n"
16161 "Host: www.example.org\r\n"
16162 "Connection: Upgrade\r\n"
16163 "Upgrade: websocket\r\n"
16164 "Origin: http://www.example.org\r\n"
16165 "Sec-WebSocket-Version: 13\r\n"
16166 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416167 };
16168
16169 // The proxy responds to the connect with a 407, using a persistent
16170 // connection.
16171 MockRead data_reads[] = {
16172 // No credentials.
16173 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16174 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416175 MockRead("Content-Length: 0\r\n"),
16176 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416177
16178 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16179
16180 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16181 MockRead("Upgrade: websocket\r\n"),
16182 MockRead("Connection: Upgrade\r\n"),
16183 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16184 };
16185
16186 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16187 arraysize(data_writes));
16188 session_deps_.socket_factory->AddSocketDataProvider(&data);
16189 SSLSocketDataProvider ssl(ASYNC, OK);
16190 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16191
bnc87dcefc2017-05-25 12:47:5816192 auto trans =
16193 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416194 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16195 trans->SetWebSocketHandshakeStreamCreateHelper(
16196 &websocket_stream_create_helper);
16197
16198 {
16199 TestCompletionCallback callback;
16200
tfarina42834112016-09-22 13:38:2016201 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416203
16204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116205 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416206 }
16207
16208 const HttpResponseInfo* response = trans->GetResponseInfo();
16209 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216210 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416211 EXPECT_EQ(407, response->headers->response_code());
16212
16213 {
16214 TestCompletionCallback callback;
16215
16216 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16217 callback.callback());
robpercival214763f2016-07-01 23:27:0116218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416219
16220 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116221 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416222 }
16223
16224 response = trans->GetResponseInfo();
16225 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216226 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416227
16228 EXPECT_EQ(101, response->headers->response_code());
16229
16230 trans.reset();
16231 session->CloseAllConnections();
16232}
16233
16234// Verify that proxy headers are not sent to the destination server when
16235// establishing a tunnel for an insecure WebSocket connection.
16236// This requires the authentication info to be injected into the auth cache
16237// due to crbug.com/395064
16238// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116239TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416240 HttpRequestInfo request;
16241 request.method = "GET";
bncce36dca22015-04-21 22:11:2316242 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416243 AddWebSocketHeaders(&request.extra_headers);
16244
16245 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316246 session_deps_.proxy_service =
16247 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416248
danakj1fd259a02016-04-16 03:17:0916249 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416250
16251 MockWrite data_writes[] = {
16252 // Try to establish a tunnel for the WebSocket connection, with
16253 // credentials. Because WebSockets have a separate set of socket pools,
16254 // they cannot and will not use the same TCP/IP connection as the
16255 // preflight HTTP request.
16256 MockWrite(
bncce36dca22015-04-21 22:11:2316257 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16258 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416259 "Proxy-Connection: keep-alive\r\n"
16260 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16261
16262 MockWrite(
16263 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316264 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416265 "Connection: Upgrade\r\n"
16266 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316267 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416268 "Sec-WebSocket-Version: 13\r\n"
16269 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16270 };
16271
16272 MockRead data_reads[] = {
16273 // HTTP CONNECT with credentials.
16274 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16275
16276 // WebSocket connection established inside tunnel.
16277 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16278 MockRead("Upgrade: websocket\r\n"),
16279 MockRead("Connection: Upgrade\r\n"),
16280 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16281 };
16282
16283 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16284 arraysize(data_writes));
16285 session_deps_.socket_factory->AddSocketDataProvider(&data);
16286
16287 session->http_auth_cache()->Add(
16288 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16289 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16290
bnc87dcefc2017-05-25 12:47:5816291 auto trans =
16292 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416293 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16294 trans->SetWebSocketHandshakeStreamCreateHelper(
16295 &websocket_stream_create_helper);
16296
16297 TestCompletionCallback callback;
16298
tfarina42834112016-09-22 13:38:2016299 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116300 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416301
16302 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116303 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416304
16305 const HttpResponseInfo* response = trans->GetResponseInfo();
16306 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216307 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416308
16309 EXPECT_EQ(101, response->headers->response_code());
16310
16311 trans.reset();
16312 session->CloseAllConnections();
16313}
16314
bncd16676a2016-07-20 16:23:0116315TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916316 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216317 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716318 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216319 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216320
16321 HttpRequestInfo request;
16322 request.method = "POST";
16323 request.url = GURL("http://www.foo.com/");
16324 request.upload_data_stream = &upload_data_stream;
16325
danakj1fd259a02016-04-16 03:17:0916326 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616327 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216328 MockWrite data_writes[] = {
16329 MockWrite("POST / HTTP/1.1\r\n"
16330 "Host: www.foo.com\r\n"
16331 "Connection: keep-alive\r\n"
16332 "Content-Length: 3\r\n\r\n"),
16333 MockWrite("foo"),
16334 };
16335
16336 MockRead data_reads[] = {
16337 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16338 MockRead(SYNCHRONOUS, OK),
16339 };
16340 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16341 arraysize(data_writes));
16342 session_deps_.socket_factory->AddSocketDataProvider(&data);
16343
16344 TestCompletionCallback callback;
16345
16346 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016347 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116348 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216349
16350 std::string response_data;
bnc691fda62016-08-12 00:43:1616351 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216352
16353 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616354 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216355 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616356 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216357}
16358
bncd16676a2016-07-20 16:23:0116359TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916360 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216361 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716362 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216363 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216364
16365 HttpRequestInfo request;
16366 request.method = "POST";
16367 request.url = GURL("http://www.foo.com/");
16368 request.upload_data_stream = &upload_data_stream;
16369
danakj1fd259a02016-04-16 03:17:0916370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616371 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216372 MockWrite data_writes[] = {
16373 MockWrite("POST / HTTP/1.1\r\n"
16374 "Host: www.foo.com\r\n"
16375 "Connection: keep-alive\r\n"
16376 "Content-Length: 3\r\n\r\n"),
16377 MockWrite("foo"),
16378 };
16379
16380 MockRead data_reads[] = {
16381 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16382 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16383 MockRead(SYNCHRONOUS, OK),
16384 };
16385 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16386 arraysize(data_writes));
16387 session_deps_.socket_factory->AddSocketDataProvider(&data);
16388
16389 TestCompletionCallback callback;
16390
16391 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016392 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116393 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216394
16395 std::string response_data;
bnc691fda62016-08-12 00:43:1616396 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216397
16398 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616399 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216400 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616401 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216402}
16403
bncd16676a2016-07-20 16:23:0116404TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216405 ChunkedUploadDataStream upload_data_stream(0);
16406
16407 HttpRequestInfo request;
16408 request.method = "POST";
16409 request.url = GURL("http://www.foo.com/");
16410 request.upload_data_stream = &upload_data_stream;
16411
danakj1fd259a02016-04-16 03:17:0916412 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216414 // Send headers successfully, but get an error while sending the body.
16415 MockWrite data_writes[] = {
16416 MockWrite("POST / HTTP/1.1\r\n"
16417 "Host: www.foo.com\r\n"
16418 "Connection: keep-alive\r\n"
16419 "Transfer-Encoding: chunked\r\n\r\n"),
16420 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16421 };
16422
16423 MockRead data_reads[] = {
16424 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16425 MockRead(SYNCHRONOUS, OK),
16426 };
16427 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16428 arraysize(data_writes));
16429 session_deps_.socket_factory->AddSocketDataProvider(&data);
16430
16431 TestCompletionCallback callback;
16432
16433 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016434 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216435
16436 base::RunLoop().RunUntilIdle();
16437 upload_data_stream.AppendData("f", 1, false);
16438
16439 base::RunLoop().RunUntilIdle();
16440 upload_data_stream.AppendData("oo", 2, true);
16441
robpercival214763f2016-07-01 23:27:0116442 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216443
16444 std::string response_data;
bnc691fda62016-08-12 00:43:1616445 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216446
16447 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616448 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216449 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616450 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216451}
16452
rdsmith1d343be52016-10-21 20:37:5016453// Confirm that transactions whose throttle is created in (and stays in)
16454// the unthrottled state are not blocked.
16455TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16456 TestNetworkStreamThrottler* throttler(nullptr);
16457 std::unique_ptr<HttpNetworkSession> session(
16458 CreateSessionWithThrottler(&session_deps_, &throttler));
16459
16460 // Send a simple request and make sure it goes through.
16461 HttpRequestInfo request;
16462 request.method = "GET";
16463 request.url = GURL("http://www.example.org/");
16464
bnc87dcefc2017-05-25 12:47:5816465 auto trans =
16466 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016467
16468 MockWrite data_writes[] = {
16469 MockWrite("GET / HTTP/1.1\r\n"
16470 "Host: www.example.org\r\n"
16471 "Connection: keep-alive\r\n\r\n"),
16472 };
16473 MockRead data_reads[] = {
16474 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16475 MockRead(SYNCHRONOUS, OK),
16476 };
16477 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16478 arraysize(data_writes));
16479 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16480
16481 TestCompletionCallback callback;
16482 trans->Start(&request, callback.callback(), NetLogWithSource());
16483 EXPECT_EQ(OK, callback.WaitForResult());
16484}
16485
16486// Confirm requests can be blocked by a throttler, and are resumed
16487// when the throttle is unblocked.
16488TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16489 TestNetworkStreamThrottler* throttler(nullptr);
16490 std::unique_ptr<HttpNetworkSession> session(
16491 CreateSessionWithThrottler(&session_deps_, &throttler));
16492
16493 // Send a simple request and make sure it goes through.
16494 HttpRequestInfo request;
16495 request.method = "GET";
16496 request.url = GURL("http://www.example.org/");
16497
16498 MockWrite data_writes[] = {
16499 MockWrite("GET / HTTP/1.1\r\n"
16500 "Host: www.example.org\r\n"
16501 "Connection: keep-alive\r\n\r\n"),
16502 };
16503 MockRead data_reads[] = {
16504 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16505 MockRead(SYNCHRONOUS, OK),
16506 };
16507 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16508 arraysize(data_writes));
16509 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16510
16511 // Start a request that will be throttled at start; confirm it
16512 // doesn't complete.
16513 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816514 auto trans =
16515 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016516
16517 TestCompletionCallback callback;
16518 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16519 EXPECT_EQ(ERR_IO_PENDING, rv);
16520
16521 base::RunLoop().RunUntilIdle();
16522 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16523 EXPECT_FALSE(callback.have_result());
16524
16525 // Confirm the request goes on to complete when unthrottled.
16526 throttler->UnthrottleAllRequests();
16527 base::RunLoop().RunUntilIdle();
16528 ASSERT_TRUE(callback.have_result());
16529 EXPECT_EQ(OK, callback.WaitForResult());
16530}
16531
16532// Destroy a request while it's throttled.
16533TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16534 TestNetworkStreamThrottler* throttler(nullptr);
16535 std::unique_ptr<HttpNetworkSession> session(
16536 CreateSessionWithThrottler(&session_deps_, &throttler));
16537
16538 // Send a simple request and make sure it goes through.
16539 HttpRequestInfo request;
16540 request.method = "GET";
16541 request.url = GURL("http://www.example.org/");
16542
16543 MockWrite data_writes[] = {
16544 MockWrite("GET / HTTP/1.1\r\n"
16545 "Host: www.example.org\r\n"
16546 "Connection: keep-alive\r\n\r\n"),
16547 };
16548 MockRead data_reads[] = {
16549 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16550 MockRead(SYNCHRONOUS, OK),
16551 };
16552 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16553 arraysize(data_writes));
16554 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16555
16556 // Start a request that will be throttled at start; confirm it
16557 // doesn't complete.
16558 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816559 auto trans =
16560 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016561
16562 TestCompletionCallback callback;
16563 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16564 EXPECT_EQ(ERR_IO_PENDING, rv);
16565
16566 base::RunLoop().RunUntilIdle();
16567 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16568 EXPECT_FALSE(callback.have_result());
16569
16570 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16571 trans.reset();
16572 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16573}
16574
16575// Confirm the throttler receives SetPriority calls.
16576TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16577 TestNetworkStreamThrottler* throttler(nullptr);
16578 std::unique_ptr<HttpNetworkSession> session(
16579 CreateSessionWithThrottler(&session_deps_, &throttler));
16580
16581 // Send a simple request and make sure it goes through.
16582 HttpRequestInfo request;
16583 request.method = "GET";
16584 request.url = GURL("http://www.example.org/");
16585
16586 MockWrite data_writes[] = {
16587 MockWrite("GET / HTTP/1.1\r\n"
16588 "Host: www.example.org\r\n"
16589 "Connection: keep-alive\r\n\r\n"),
16590 };
16591 MockRead data_reads[] = {
16592 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16593 MockRead(SYNCHRONOUS, OK),
16594 };
16595 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16596 arraysize(data_writes));
16597 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16598
16599 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816600 auto trans = base::MakeUnique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016601 // Start the transaction to associate a throttle with it.
16602 TestCompletionCallback callback;
16603 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16604 EXPECT_EQ(ERR_IO_PENDING, rv);
16605
16606 EXPECT_EQ(0, throttler->num_set_priority_calls());
16607 trans->SetPriority(LOW);
16608 EXPECT_EQ(1, throttler->num_set_priority_calls());
16609 EXPECT_EQ(LOW, throttler->last_priority_set());
16610
16611 throttler->UnthrottleAllRequests();
16612 base::RunLoop().RunUntilIdle();
16613 ASSERT_TRUE(callback.have_result());
16614 EXPECT_EQ(OK, callback.WaitForResult());
16615}
16616
16617// Confirm that unthrottling from a SetPriority call by the
16618// throttler works properly.
16619TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16620 TestNetworkStreamThrottler* throttler(nullptr);
16621 std::unique_ptr<HttpNetworkSession> session(
16622 CreateSessionWithThrottler(&session_deps_, &throttler));
16623
16624 // Send a simple request and make sure it goes through.
16625 HttpRequestInfo request;
16626 request.method = "GET";
16627 request.url = GURL("http://www.example.org/");
16628
16629 MockWrite data_writes[] = {
16630 MockWrite("GET / HTTP/1.1\r\n"
16631 "Host: www.example.org\r\n"
16632 "Connection: keep-alive\r\n\r\n"),
16633 };
16634 MockRead data_reads[] = {
16635 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16636 MockRead(SYNCHRONOUS, OK),
16637 };
16638 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16639 arraysize(data_writes));
16640 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16641
16642 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16643 data_writes, arraysize(data_writes));
16644 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16645
16646 // Start a request that will be throttled at start; confirm it
16647 // doesn't complete.
16648 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816649 auto trans =
16650 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016651
16652 TestCompletionCallback callback;
16653 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16654 EXPECT_EQ(ERR_IO_PENDING, rv);
16655
16656 base::RunLoop().RunUntilIdle();
16657 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16658 EXPECT_FALSE(callback.have_result());
16659
16660 // Create a new request, call SetPriority on it to unthrottle,
16661 // and make sure that allows the original request to complete.
bnc87dcefc2017-05-25 12:47:5816662 auto trans1 = base::MakeUnique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5016663 throttler->set_priority_change_closure(
16664 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16665 base::Unretained(throttler)));
16666
16667 // Start the transaction to associate a throttle with it.
16668 TestCompletionCallback callback1;
16669 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16670 EXPECT_EQ(ERR_IO_PENDING, rv);
16671
16672 trans1->SetPriority(IDLE);
16673
16674 base::RunLoop().RunUntilIdle();
16675 ASSERT_TRUE(callback.have_result());
16676 EXPECT_EQ(OK, callback.WaitForResult());
16677 ASSERT_TRUE(callback1.have_result());
16678 EXPECT_EQ(OK, callback1.WaitForResult());
16679}
16680
16681// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5816682void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5016683
16684// Confirm that destroying a transaction from a SetPriority call by the
16685// throttler works properly.
16686TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16687 TestNetworkStreamThrottler* throttler(nullptr);
16688 std::unique_ptr<HttpNetworkSession> session(
16689 CreateSessionWithThrottler(&session_deps_, &throttler));
16690
16691 // Send a simple request and make sure it goes through.
16692 HttpRequestInfo request;
16693 request.method = "GET";
16694 request.url = GURL("http://www.example.org/");
16695
16696 MockWrite data_writes[] = {
16697 MockWrite("GET / HTTP/1.1\r\n"
16698 "Host: www.example.org\r\n"
16699 "Connection: keep-alive\r\n\r\n"),
16700 };
16701 MockRead data_reads[] = {
16702 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16703 MockRead(SYNCHRONOUS, OK),
16704 };
16705 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16706 arraysize(data_writes));
16707 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16708
16709 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16710 data_writes, arraysize(data_writes));
16711 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16712
16713 // Start a request that will be throttled at start; confirm it
16714 // doesn't complete.
16715 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816716 auto trans =
16717 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016718
16719 TestCompletionCallback callback;
16720 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16721 EXPECT_EQ(ERR_IO_PENDING, rv);
16722
16723 base::RunLoop().RunUntilIdle();
16724 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16725 EXPECT_FALSE(callback.have_result());
16726
16727 // Arrange for the set priority call on the above transaction to delete
16728 // the transaction.
bnc87dcefc2017-05-25 12:47:5816729 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5016730 throttler->set_priority_change_closure(
16731 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16732
16733 // Call it and check results (partially a "doesn't crash" test).
16734 trans_ptr->SetPriority(IDLE);
16735 trans_ptr = nullptr; // No longer a valid pointer.
16736
16737 base::RunLoop().RunUntilIdle();
16738 ASSERT_FALSE(callback.have_result());
16739}
16740
nharperb7441ef2016-01-25 23:54:1416741#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116742TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416743 const std::string https_url = "https://www.example.com";
16744 HttpRequestInfo request;
16745 request.url = GURL(https_url);
16746 request.method = "GET";
16747
16748 SSLSocketDataProvider ssl(ASYNC, OK);
16749 ssl.token_binding_negotiated = true;
16750 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616751 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416752 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16753
bnc42331402016-07-25 13:36:1516754 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116755 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16756 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416757 MockRead(ASYNC, ERR_IO_PENDING)};
16758 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16759 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5816760 session_deps_.channel_id_service =
16761 base::MakeUnique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0916762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416763
16764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16765 TestCompletionCallback callback;
16766 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016767 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1016768
16769 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416770
16771 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16772 HttpRequestHeaders headers;
16773 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16774 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16775}
16776#endif // !defined(OS_IOS)
16777
eustasc7d27da2017-04-06 10:33:2016778void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
16779 const std::string& accept_encoding,
16780 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0316781 const std::string& location,
eustasc7d27da2017-04-06 10:33:2016782 bool should_match) {
16783 HttpRequestInfo request;
16784 request.method = "GET";
16785 request.url = GURL("http://www.foo.com/");
16786 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
16787 accept_encoding);
16788
16789 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
16790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16791 // Send headers successfully, but get an error while sending the body.
16792 MockWrite data_writes[] = {
16793 MockWrite("GET / HTTP/1.1\r\n"
16794 "Host: www.foo.com\r\n"
16795 "Connection: keep-alive\r\n"
16796 "Accept-Encoding: "),
16797 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
16798 };
16799
sky50576f32017-05-01 19:28:0316800 std::string response_code = "200 OK";
16801 std::string extra;
16802 if (!location.empty()) {
16803 response_code = "301 Redirect\r\nLocation: ";
16804 response_code.append(location);
16805 }
16806
eustasc7d27da2017-04-06 10:33:2016807 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0316808 MockRead("HTTP/1.0 "),
16809 MockRead(response_code.data()),
16810 MockRead("\r\nContent-Encoding: "),
16811 MockRead(content_encoding.data()),
16812 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2016813 MockRead(SYNCHRONOUS, OK),
16814 };
16815 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16816 arraysize(data_writes));
16817 session_deps->socket_factory->AddSocketDataProvider(&data);
16818
16819 TestCompletionCallback callback;
16820
16821 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16823
16824 rv = callback.WaitForResult();
16825 if (should_match) {
16826 EXPECT_THAT(rv, IsOk());
16827 } else {
16828 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
16829 }
16830}
16831
16832TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0316833 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2016834}
16835
16836TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0316837 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
16838 true);
eustasc7d27da2017-04-06 10:33:2016839}
16840
16841TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
16842 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0316843 "", false);
16844}
16845
16846TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
16847 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
16848 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2016849}
16850
xunjieli96f2a402017-06-05 17:24:2716851TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
16852 ProxyConfig proxy_config;
16853 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
16854 proxy_config.set_pac_mandatory(true);
16855 MockAsyncProxyResolver resolver;
16856 session_deps_.proxy_service.reset(new ProxyService(
16857 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
16858 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
16859
16860 HttpRequestInfo request;
16861 request.method = "GET";
16862 request.url = GURL("http://www.example.org/");
16863
16864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16865 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16866
16867 TestCompletionCallback callback;
16868
16869 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16870 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16871 EXPECT_THAT(callback.WaitForResult(),
16872 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
16873}
16874
16875TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
16876 ProxyConfig proxy_config;
16877 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
16878 proxy_config.set_pac_mandatory(true);
16879 MockAsyncProxyResolverFactory* proxy_resolver_factory =
16880 new MockAsyncProxyResolverFactory(false);
16881 MockAsyncProxyResolver resolver;
16882 session_deps_.proxy_service.reset(
16883 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
16884 base::WrapUnique(proxy_resolver_factory), nullptr));
16885 HttpRequestInfo request;
16886 request.method = "GET";
16887 request.url = GURL("http://www.example.org/");
16888
16889 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16891
16892 TestCompletionCallback callback;
16893 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16895
16896 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
16897 ERR_FAILED, &resolver);
16898 EXPECT_THAT(callback.WaitForResult(),
16899 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
16900}
16901
16902TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
16903 session_deps_.proxy_service =
16904 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
16905 session_deps_.enable_quic = false;
16906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16907
16908 HttpRequestInfo request;
16909 request.method = "GET";
16910 request.url = GURL("http://www.example.org/");
16911
16912 TestCompletionCallback callback;
16913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16914 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16916
16917 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
16918}
16919
[email protected]89ceba9a2009-03-21 03:46:0616920} // namespace net