blob: 80c62f89b77c42a8dd8202a0f814eaa0ef94ab06 [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
Biljith Jayan45a41722017-08-16 18:43:141682// Test that we do not retry indefinitely when a server sends an error like
1683// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1684// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1685TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1686 HttpRequestInfo request;
1687 request.method = "GET";
1688 request.url = GURL("https://www.foo.com/");
1689
1690 // Check whether we give up after the third try.
1691
1692 // Construct an HTTP2 request and a "Go away" response.
1693 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1694 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1695 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1696 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1697 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1698
1699 // Three go away responses.
1700 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1701 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1702 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1703
1704 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1705 AddSSLSocketData();
1706 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1707 AddSSLSocketData();
1708 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1709 AddSSLSocketData();
1710
1711 TestCompletionCallback callback;
1712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1713 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1714
1715 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1717
1718 rv = callback.WaitForResult();
1719 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1720}
1721
1722TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1723 HttpRequestInfo request;
1724 request.method = "GET";
1725 request.url = GURL("https://www.foo.com/");
1726
1727 // Check whether we try atleast thrice before giving up.
1728
1729 // Construct an HTTP2 request and a "Go away" response.
1730 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1731 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1732 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1733 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1734 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1735
1736 // Construct a non error HTTP2 response.
1737 SpdySerializedFrame spdy_response_no_error(
1738 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1739 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1740 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1741 CreateMockRead(spdy_data, 2)};
1742
1743 // Two error responses.
1744 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1745 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1746 // Followed by a success response.
1747 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1748
1749 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1750 AddSSLSocketData();
1751 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1752 AddSSLSocketData();
1753 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1754 AddSSLSocketData();
1755
1756 TestCompletionCallback callback;
1757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1759
1760 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1761 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1762
1763 rv = callback.WaitForResult();
1764 EXPECT_THAT(rv, IsOk());
1765}
1766
bncd16676a2016-07-20 16:23:011767TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061768 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511769 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1770}
1771
bncd16676a2016-07-20 16:23:011772TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061773 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511774 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251775}
1776
bncd16676a2016-07-20 16:23:011777TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061778 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511779 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251780}
1781
[email protected]d58ceea82014-06-04 10:55:541782// Make sure that on a 408 response (Request Timeout), the request is retried,
1783// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011784TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541785 MockRead read_failure(SYNCHRONOUS,
1786 "HTTP/1.1 408 Request Timeout\r\n"
1787 "Connection: Keep-Alive\r\n"
1788 "Content-Length: 6\r\n\r\n"
1789 "Pickle");
1790 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1791}
1792
bncd16676a2016-07-20 16:23:011793TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491794 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101795 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491796}
1797
bncd16676a2016-07-20 16:23:011798TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491799 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101800 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491801}
1802
bncd16676a2016-07-20 16:23:011803TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491804 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101805 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1806}
1807
bncd16676a2016-07-20 16:23:011808TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101809 MockRead read_failure(ASYNC, OK); // EOF
1810 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1811}
1812
[email protected]d58ceea82014-06-04 10:55:541813// Make sure that on a 408 response (Request Timeout), the request is retried,
1814// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011815TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541816 MockRead read_failure(SYNCHRONOUS,
1817 "HTTP/1.1 408 Request Timeout\r\n"
1818 "Connection: Keep-Alive\r\n"
1819 "Content-Length: 6\r\n\r\n"
1820 "Pickle");
1821 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1822 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1823}
1824
bncd16676a2016-07-20 16:23:011825TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101826 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1827 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1828}
1829
bncd16676a2016-07-20 16:23:011830TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101831 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1832 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1833}
1834
bncd16676a2016-07-20 16:23:011835TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101836 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1837 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1838}
1839
bncd16676a2016-07-20 16:23:011840TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101841 MockRead read_failure(ASYNC, OK); // EOF
1842 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491843}
1844
bncd16676a2016-07-20 16:23:011845TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421846 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251847 request.method = "GET";
bncce36dca22015-04-21 22:11:231848 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251849
danakj1fd259a02016-04-16 03:17:091850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161851 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271852
[email protected]3d2a59b2008-09-26 19:44:251853 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061854 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351855 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1856 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061857 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251858 };
[email protected]31a2bfe2010-02-09 08:03:391859 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071860 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251861
[email protected]49639fa2011-12-20 23:22:411862 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251863
tfarina42834112016-09-22 13:38:201864 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251866
1867 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011868 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591869
1870 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161871 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591872 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251873}
1874
1875// What do various browsers do when the server closes a non-keepalive
1876// connection without sending any response header or body?
1877//
1878// IE7: error page
1879// Safari 3.1.2 (Windows): error page
1880// Firefox 3.0.1: blank page
1881// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421882// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1883// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011884TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251885 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061886 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351887 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1888 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061889 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251890 };
[email protected]31a2bfe2010-02-09 08:03:391891 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1892 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011893 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251894}
[email protected]1826a402014-01-08 15:40:481895
[email protected]7a5378b2012-11-04 03:25:171896// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1897// tests. There was a bug causing HttpNetworkTransaction to hang in the
1898// destructor in such situations.
1899// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011900TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171901 HttpRequestInfo request;
1902 request.method = "GET";
bncce36dca22015-04-21 22:11:231903 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171904
danakj1fd259a02016-04-16 03:17:091905 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581906 auto trans =
1907 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171908
1909 MockRead data_reads[] = {
1910 MockRead("HTTP/1.0 200 OK\r\n"),
1911 MockRead("Connection: keep-alive\r\n"),
1912 MockRead("Content-Length: 100\r\n\r\n"),
1913 MockRead("hello"),
1914 MockRead(SYNCHRONOUS, 0),
1915 };
1916 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071917 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171918
1919 TestCompletionCallback callback;
1920
tfarina42834112016-09-22 13:38:201921 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171923
1924 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011925 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171926
1927 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501928 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171929 if (rv == ERR_IO_PENDING)
1930 rv = callback.WaitForResult();
1931 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501932 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011933 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171934
1935 trans.reset();
fdoray92e35a72016-06-10 15:54:551936 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171937 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1938}
1939
bncd16676a2016-07-20 16:23:011940TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171941 HttpRequestInfo request;
1942 request.method = "GET";
bncce36dca22015-04-21 22:11:231943 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171944
danakj1fd259a02016-04-16 03:17:091945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581946 auto trans =
1947 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171948
1949 MockRead data_reads[] = {
1950 MockRead("HTTP/1.0 200 OK\r\n"),
1951 MockRead("Connection: keep-alive\r\n"),
1952 MockRead("Content-Length: 100\r\n\r\n"),
1953 MockRead(SYNCHRONOUS, 0),
1954 };
1955 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071956 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171957
1958 TestCompletionCallback callback;
1959
tfarina42834112016-09-22 13:38:201960 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171962
1963 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011964 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171965
1966 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501967 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171968 if (rv == ERR_IO_PENDING)
1969 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011970 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171971
1972 trans.reset();
fdoray92e35a72016-06-10 15:54:551973 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171974 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1975}
1976
[email protected]0b0bf032010-09-21 18:08:501977// Test that we correctly reuse a keep-alive connection after not explicitly
1978// reading the body.
bncd16676a2016-07-20 16:23:011979TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131980 HttpRequestInfo request;
1981 request.method = "GET";
1982 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131983
vishal.b62985ca92015-04-17 08:45:511984 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071985 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091986 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271987
mmenkecc2298e2015-12-07 18:20:181988 const char* request_data =
1989 "GET / HTTP/1.1\r\n"
1990 "Host: www.foo.com\r\n"
1991 "Connection: keep-alive\r\n\r\n";
1992 MockWrite data_writes[] = {
1993 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1994 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1995 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1996 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1997 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1998 };
1999
[email protected]0b0bf032010-09-21 18:08:502000 // Note that because all these reads happen in the same
2001 // StaticSocketDataProvider, it shows that the same socket is being reused for
2002 // all transactions.
mmenkecc2298e2015-12-07 18:20:182003 MockRead data_reads[] = {
2004 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2005 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2006 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2007 MockRead(ASYNC, 7,
2008 "HTTP/1.1 302 Found\r\n"
2009 "Content-Length: 0\r\n\r\n"),
2010 MockRead(ASYNC, 9,
2011 "HTTP/1.1 302 Found\r\n"
2012 "Content-Length: 5\r\n\r\n"
2013 "hello"),
2014 MockRead(ASYNC, 11,
2015 "HTTP/1.1 301 Moved Permanently\r\n"
2016 "Content-Length: 0\r\n\r\n"),
2017 MockRead(ASYNC, 13,
2018 "HTTP/1.1 301 Moved Permanently\r\n"
2019 "Content-Length: 5\r\n\r\n"
2020 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132021
mmenkecc2298e2015-12-07 18:20:182022 // In the next two rounds, IsConnectedAndIdle returns false, due to
2023 // the set_busy_before_sync_reads(true) call, while the
2024 // HttpNetworkTransaction is being shut down, but the socket is still
2025 // reuseable. See http://crbug.com/544255.
2026 MockRead(ASYNC, 15,
2027 "HTTP/1.1 200 Hunky-Dory\r\n"
2028 "Content-Length: 5\r\n\r\n"),
2029 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132030
mmenkecc2298e2015-12-07 18:20:182031 MockRead(ASYNC, 18,
2032 "HTTP/1.1 200 Hunky-Dory\r\n"
2033 "Content-Length: 5\r\n\r\n"
2034 "he"),
2035 MockRead(SYNCHRONOUS, 19, "llo"),
2036
2037 // The body of the final request is actually read.
2038 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2039 MockRead(ASYNC, 22, "hello"),
2040 };
2041 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2042 arraysize(data_writes));
2043 data.set_busy_before_sync_reads(true);
2044 session_deps_.socket_factory->AddSocketDataProvider(&data);
2045
2046 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502047 std::string response_lines[kNumUnreadBodies];
2048
mikecironef22f9812016-10-04 03:40:192049 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182050 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412051 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132052
bnc87dcefc2017-05-25 12:47:582053 auto trans = base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
2054 session.get());
[email protected]fc31d6a42010-06-24 18:05:132055
tfarina42834112016-09-22 13:38:202056 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012057 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132058
[email protected]58e32bb2013-01-21 18:23:252059 LoadTimingInfo load_timing_info;
2060 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2061 if (i == 0) {
2062 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2063 first_socket_log_id = load_timing_info.socket_log_id;
2064 } else {
2065 TestLoadTimingReused(load_timing_info);
2066 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2067 }
2068
[email protected]fc31d6a42010-06-24 18:05:132069 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182070 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132071
mmenkecc2298e2015-12-07 18:20:182072 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502073 response_lines[i] = response->headers->GetStatusLine();
2074
mmenkecc2298e2015-12-07 18:20:182075 // Delete the transaction without reading the response bodies. Then spin
2076 // the message loop, so the response bodies are drained.
2077 trans.reset();
2078 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132079 }
[email protected]0b0bf032010-09-21 18:08:502080
2081 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182082 "HTTP/1.1 204 No Content",
2083 "HTTP/1.1 205 Reset Content",
2084 "HTTP/1.1 304 Not Modified",
2085 "HTTP/1.1 302 Found",
2086 "HTTP/1.1 302 Found",
2087 "HTTP/1.1 301 Moved Permanently",
2088 "HTTP/1.1 301 Moved Permanently",
2089 "HTTP/1.1 200 Hunky-Dory",
2090 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502091 };
2092
mostynb91e0da982015-01-20 19:17:272093 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2094 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502095
2096 for (int i = 0; i < kNumUnreadBodies; ++i)
2097 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2098
[email protected]49639fa2011-12-20 23:22:412099 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202101 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012102 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162103 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182104 ASSERT_TRUE(response);
2105 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502106 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2107 std::string response_data;
bnc691fda62016-08-12 00:43:162108 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012109 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502110 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132111}
2112
mmenke5f94fda2016-06-02 20:54:132113// Sockets that receive extra data after a response is complete should not be
2114// reused.
bncd16676a2016-07-20 16:23:012115TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132116 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2117 MockWrite data_writes1[] = {
2118 MockWrite("HEAD / HTTP/1.1\r\n"
2119 "Host: www.borked.com\r\n"
2120 "Connection: keep-alive\r\n\r\n"),
2121 };
2122
2123 MockRead data_reads1[] = {
2124 MockRead("HTTP/1.1 200 OK\r\n"
2125 "Connection: keep-alive\r\n"
2126 "Content-Length: 22\r\n\r\n"
2127 "This server is borked."),
2128 };
2129
2130 MockWrite data_writes2[] = {
2131 MockWrite("GET /foo HTTP/1.1\r\n"
2132 "Host: www.borked.com\r\n"
2133 "Connection: keep-alive\r\n\r\n"),
2134 };
2135
2136 MockRead data_reads2[] = {
2137 MockRead("HTTP/1.1 200 OK\r\n"
2138 "Content-Length: 3\r\n\r\n"
2139 "foo"),
2140 };
2141 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2142 data_writes1, arraysize(data_writes1));
2143 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2144 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2145 data_writes2, arraysize(data_writes2));
2146 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2147
2148 TestCompletionCallback callback;
2149 HttpRequestInfo request1;
2150 request1.method = "HEAD";
2151 request1.url = GURL("http://www.borked.com/");
2152
bnc87dcefc2017-05-25 12:47:582153 auto trans1 =
2154 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202155 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012156 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132157
2158 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2159 ASSERT_TRUE(response1);
2160 ASSERT_TRUE(response1->headers);
2161 EXPECT_EQ(200, response1->headers->response_code());
2162 EXPECT_TRUE(response1->headers->IsKeepAlive());
2163
2164 std::string response_data1;
robpercival214763f2016-07-01 23:27:012165 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132166 EXPECT_EQ("", response_data1);
2167 // Deleting the transaction attempts to release the socket back into the
2168 // socket pool.
2169 trans1.reset();
2170
2171 HttpRequestInfo request2;
2172 request2.method = "GET";
2173 request2.url = GURL("http://www.borked.com/foo");
2174
bnc87dcefc2017-05-25 12:47:582175 auto trans2 =
2176 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202177 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012178 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132179
2180 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2181 ASSERT_TRUE(response2);
2182 ASSERT_TRUE(response2->headers);
2183 EXPECT_EQ(200, response2->headers->response_code());
2184
2185 std::string response_data2;
robpercival214763f2016-07-01 23:27:012186 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132187 EXPECT_EQ("foo", response_data2);
2188}
2189
bncd16676a2016-07-20 16:23:012190TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2192 MockWrite data_writes1[] = {
2193 MockWrite("GET / HTTP/1.1\r\n"
2194 "Host: www.borked.com\r\n"
2195 "Connection: keep-alive\r\n\r\n"),
2196 };
2197
2198 MockRead data_reads1[] = {
2199 MockRead("HTTP/1.1 200 OK\r\n"
2200 "Connection: keep-alive\r\n"
2201 "Content-Length: 22\r\n\r\n"
2202 "This server is borked."
2203 "Bonus data!"),
2204 };
2205
2206 MockWrite data_writes2[] = {
2207 MockWrite("GET /foo HTTP/1.1\r\n"
2208 "Host: www.borked.com\r\n"
2209 "Connection: keep-alive\r\n\r\n"),
2210 };
2211
2212 MockRead data_reads2[] = {
2213 MockRead("HTTP/1.1 200 OK\r\n"
2214 "Content-Length: 3\r\n\r\n"
2215 "foo"),
2216 };
2217 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2218 data_writes1, arraysize(data_writes1));
2219 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2220 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2221 data_writes2, arraysize(data_writes2));
2222 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2223
2224 TestCompletionCallback callback;
2225 HttpRequestInfo request1;
2226 request1.method = "GET";
2227 request1.url = GURL("http://www.borked.com/");
2228
bnc87dcefc2017-05-25 12:47:582229 auto trans1 =
2230 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202231 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012232 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132233
2234 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2235 ASSERT_TRUE(response1);
2236 ASSERT_TRUE(response1->headers);
2237 EXPECT_EQ(200, response1->headers->response_code());
2238 EXPECT_TRUE(response1->headers->IsKeepAlive());
2239
2240 std::string response_data1;
robpercival214763f2016-07-01 23:27:012241 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132242 EXPECT_EQ("This server is borked.", response_data1);
2243 // Deleting the transaction attempts to release the socket back into the
2244 // socket pool.
2245 trans1.reset();
2246
2247 HttpRequestInfo request2;
2248 request2.method = "GET";
2249 request2.url = GURL("http://www.borked.com/foo");
2250
bnc87dcefc2017-05-25 12:47:582251 auto trans2 =
2252 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202253 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012254 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132255
2256 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2257 ASSERT_TRUE(response2);
2258 ASSERT_TRUE(response2->headers);
2259 EXPECT_EQ(200, response2->headers->response_code());
2260
2261 std::string response_data2;
robpercival214763f2016-07-01 23:27:012262 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132263 EXPECT_EQ("foo", response_data2);
2264}
2265
bncd16676a2016-07-20 16:23:012266TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132267 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2268 MockWrite data_writes1[] = {
2269 MockWrite("GET / HTTP/1.1\r\n"
2270 "Host: www.borked.com\r\n"
2271 "Connection: keep-alive\r\n\r\n"),
2272 };
2273
2274 MockRead data_reads1[] = {
2275 MockRead("HTTP/1.1 200 OK\r\n"
2276 "Connection: keep-alive\r\n"
2277 "Transfer-Encoding: chunked\r\n\r\n"),
2278 MockRead("16\r\nThis server is borked.\r\n"),
2279 MockRead("0\r\n\r\nBonus data!"),
2280 };
2281
2282 MockWrite data_writes2[] = {
2283 MockWrite("GET /foo HTTP/1.1\r\n"
2284 "Host: www.borked.com\r\n"
2285 "Connection: keep-alive\r\n\r\n"),
2286 };
2287
2288 MockRead data_reads2[] = {
2289 MockRead("HTTP/1.1 200 OK\r\n"
2290 "Content-Length: 3\r\n\r\n"
2291 "foo"),
2292 };
2293 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2294 data_writes1, arraysize(data_writes1));
2295 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2296 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2297 data_writes2, arraysize(data_writes2));
2298 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2299
2300 TestCompletionCallback callback;
2301 HttpRequestInfo request1;
2302 request1.method = "GET";
2303 request1.url = GURL("http://www.borked.com/");
2304
bnc87dcefc2017-05-25 12:47:582305 auto trans1 =
2306 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202307 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012308 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132309
2310 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2311 ASSERT_TRUE(response1);
2312 ASSERT_TRUE(response1->headers);
2313 EXPECT_EQ(200, response1->headers->response_code());
2314 EXPECT_TRUE(response1->headers->IsKeepAlive());
2315
2316 std::string response_data1;
robpercival214763f2016-07-01 23:27:012317 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132318 EXPECT_EQ("This server is borked.", response_data1);
2319 // Deleting the transaction attempts to release the socket back into the
2320 // socket pool.
2321 trans1.reset();
2322
2323 HttpRequestInfo request2;
2324 request2.method = "GET";
2325 request2.url = GURL("http://www.borked.com/foo");
2326
bnc87dcefc2017-05-25 12:47:582327 auto trans2 =
2328 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202329 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012330 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132331
2332 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2333 ASSERT_TRUE(response2);
2334 ASSERT_TRUE(response2->headers);
2335 EXPECT_EQ(200, response2->headers->response_code());
2336
2337 std::string response_data2;
robpercival214763f2016-07-01 23:27:012338 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132339 EXPECT_EQ("foo", response_data2);
2340}
2341
2342// This is a little different from the others - it tests the case that the
2343// HttpStreamParser doesn't know if there's extra data on a socket or not when
2344// the HttpNetworkTransaction is torn down, because the response body hasn't
2345// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012346TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2348 MockWrite data_writes1[] = {
2349 MockWrite("GET / HTTP/1.1\r\n"
2350 "Host: www.borked.com\r\n"
2351 "Connection: keep-alive\r\n\r\n"),
2352 };
2353
2354 MockRead data_reads1[] = {
2355 MockRead("HTTP/1.1 200 OK\r\n"
2356 "Connection: keep-alive\r\n"
2357 "Transfer-Encoding: chunked\r\n\r\n"),
2358 MockRead("16\r\nThis server is borked.\r\n"),
2359 MockRead("0\r\n\r\nBonus data!"),
2360 };
2361 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2362 data_writes1, arraysize(data_writes1));
2363 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2364
2365 TestCompletionCallback callback;
2366 HttpRequestInfo request1;
2367 request1.method = "GET";
2368 request1.url = GURL("http://www.borked.com/");
2369
bnc87dcefc2017-05-25 12:47:582370 auto trans =
2371 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2372 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012373 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132374
bnc87dcefc2017-05-25 12:47:582375 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132376 ASSERT_TRUE(response1);
2377 ASSERT_TRUE(response1->headers);
2378 EXPECT_EQ(200, response1->headers->response_code());
2379 EXPECT_TRUE(response1->headers->IsKeepAlive());
2380
2381 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2382 // response body.
bnc87dcefc2017-05-25 12:47:582383 trans.reset();
mmenke5f94fda2016-06-02 20:54:132384
2385 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2386 // socket can't be reused, rather than returning it to the socket pool.
2387 base::RunLoop().RunUntilIdle();
2388
2389 // There should be no idle sockets in the pool.
2390 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2391}
2392
[email protected]038e9a32008-10-08 22:40:162393// Test the request-challenge-retry sequence for basic auth.
2394// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012395TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422396 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162397 request.method = "GET";
bncce36dca22015-04-21 22:11:232398 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162399
vishal.b62985ca92015-04-17 08:45:512400 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072401 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272404
[email protected]f9ee6b52008-11-08 06:46:232405 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232406 MockWrite(
2407 "GET / HTTP/1.1\r\n"
2408 "Host: www.example.org\r\n"
2409 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232410 };
2411
[email protected]038e9a32008-10-08 22:40:162412 MockRead data_reads1[] = {
2413 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2414 // Give a couple authenticate options (only the middle one is actually
2415 // supported).
[email protected]22927ad2009-09-21 19:56:192416 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162417 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2418 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2419 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2420 // Large content-length -- won't matter, as connection will be reset.
2421 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062422 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162423 };
2424
2425 // After calling trans->RestartWithAuth(), this is the request we should
2426 // be issuing -- the final header line contains the credentials.
2427 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232428 MockWrite(
2429 "GET / HTTP/1.1\r\n"
2430 "Host: www.example.org\r\n"
2431 "Connection: keep-alive\r\n"
2432 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162433 };
2434
2435 // Lastly, the server responds with the actual content.
2436 MockRead data_reads2[] = {
2437 MockRead("HTTP/1.0 200 OK\r\n"),
2438 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2439 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062440 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162441 };
2442
[email protected]31a2bfe2010-02-09 08:03:392443 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2444 data_writes1, arraysize(data_writes1));
2445 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2446 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072447 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2448 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162449
[email protected]49639fa2011-12-20 23:22:412450 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162451
tfarina42834112016-09-22 13:38:202452 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162454
2455 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012456 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162457
[email protected]58e32bb2013-01-21 18:23:252458 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162459 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252460 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2461
sclittlefb249892015-09-10 21:33:222462 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162463 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222464 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162465 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192466
bnc691fda62016-08-12 00:43:162467 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522468 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042469 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162470
[email protected]49639fa2011-12-20 23:22:412471 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162472
bnc691fda62016-08-12 00:43:162473 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162475
2476 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012477 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162478
[email protected]58e32bb2013-01-21 18:23:252479 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162480 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252481 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2482 // The load timing after restart should have a new socket ID, and times after
2483 // those of the first load timing.
2484 EXPECT_LE(load_timing_info1.receive_headers_end,
2485 load_timing_info2.connect_timing.connect_start);
2486 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2487
sclittlefb249892015-09-10 21:33:222488 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162489 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222490 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162491 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192492
bnc691fda62016-08-12 00:43:162493 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522494 ASSERT_TRUE(response);
2495 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162496 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162497}
2498
ttuttled9dbc652015-09-29 20:00:592499// Test the request-challenge-retry sequence for basic auth.
2500// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012501TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592502 HttpRequestInfo request;
2503 request.method = "GET";
2504 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592505
2506 TestNetLog log;
2507 MockHostResolver* resolver = new MockHostResolver();
2508 session_deps_.net_log = &log;
2509 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092510 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592512
2513 resolver->rules()->ClearRules();
2514 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2515
2516 MockWrite data_writes1[] = {
2517 MockWrite("GET / HTTP/1.1\r\n"
2518 "Host: www.example.org\r\n"
2519 "Connection: keep-alive\r\n\r\n"),
2520 };
2521
2522 MockRead data_reads1[] = {
2523 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2524 // Give a couple authenticate options (only the middle one is actually
2525 // supported).
2526 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2527 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2528 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2529 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2530 // Large content-length -- won't matter, as connection will be reset.
2531 MockRead("Content-Length: 10000\r\n\r\n"),
2532 MockRead(SYNCHRONOUS, ERR_FAILED),
2533 };
2534
2535 // After calling trans->RestartWithAuth(), this is the request we should
2536 // be issuing -- the final header line contains the credentials.
2537 MockWrite data_writes2[] = {
2538 MockWrite("GET / HTTP/1.1\r\n"
2539 "Host: www.example.org\r\n"
2540 "Connection: keep-alive\r\n"
2541 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2542 };
2543
2544 // Lastly, the server responds with the actual content.
2545 MockRead data_reads2[] = {
2546 MockRead("HTTP/1.0 200 OK\r\n"),
2547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2548 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2549 };
2550
2551 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2552 data_writes1, arraysize(data_writes1));
2553 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2554 data_writes2, arraysize(data_writes2));
2555 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2556 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2557
2558 TestCompletionCallback callback1;
2559
bnc691fda62016-08-12 00:43:162560 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202561 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592562
2563 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162564 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592565 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2566
2567 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162568 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592569 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162570 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592571
bnc691fda62016-08-12 00:43:162572 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592573 ASSERT_TRUE(response);
2574 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2575
2576 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162577 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592578 ASSERT_FALSE(endpoint.address().empty());
2579 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2580
2581 resolver->rules()->ClearRules();
2582 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2583
2584 TestCompletionCallback callback2;
2585
bnc691fda62016-08-12 00:43:162586 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592587 AuthCredentials(kFoo, kBar), callback2.callback())));
2588
2589 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162590 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592591 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2592 // The load timing after restart should have a new socket ID, and times after
2593 // those of the first load timing.
2594 EXPECT_LE(load_timing_info1.receive_headers_end,
2595 load_timing_info2.connect_timing.connect_start);
2596 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2597
2598 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162599 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592600 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162601 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592602
bnc691fda62016-08-12 00:43:162603 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592604 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522605 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592606 EXPECT_EQ(100, response->headers->GetContentLength());
2607
bnc691fda62016-08-12 00:43:162608 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592609 ASSERT_FALSE(endpoint.address().empty());
2610 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2611}
2612
bncd16676a2016-07-20 16:23:012613TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462614 HttpRequestInfo request;
2615 request.method = "GET";
bncce36dca22015-04-21 22:11:232616 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292617 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462618
danakj1fd259a02016-04-16 03:17:092619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162620 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272621
[email protected]861fcd52009-08-26 02:33:462622 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232623 MockWrite(
2624 "GET / HTTP/1.1\r\n"
2625 "Host: www.example.org\r\n"
2626 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462627 };
2628
2629 MockRead data_reads[] = {
2630 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2631 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2632 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2633 // Large content-length -- won't matter, as connection will be reset.
2634 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062635 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462636 };
2637
[email protected]31a2bfe2010-02-09 08:03:392638 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2639 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072640 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412641 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462642
tfarina42834112016-09-22 13:38:202643 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462645
2646 rv = callback.WaitForResult();
2647 EXPECT_EQ(0, rv);
2648
sclittlefb249892015-09-10 21:33:222649 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162650 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222651 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162652 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192653
bnc691fda62016-08-12 00:43:162654 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522655 ASSERT_TRUE(response);
2656 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462657}
2658
[email protected]2d2697f92009-02-18 21:00:322659// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2660// connection.
bncd16676a2016-07-20 16:23:012661TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182662 // On the second pass, the body read of the auth challenge is synchronous, so
2663 // IsConnectedAndIdle returns false. The socket should still be drained and
2664 // reused. See http://crbug.com/544255.
2665 for (int i = 0; i < 2; ++i) {
2666 HttpRequestInfo request;
2667 request.method = "GET";
2668 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322669
mmenkecc2298e2015-12-07 18:20:182670 TestNetLog log;
2671 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272673
mmenkecc2298e2015-12-07 18:20:182674 MockWrite data_writes[] = {
2675 MockWrite(ASYNC, 0,
2676 "GET / HTTP/1.1\r\n"
2677 "Host: www.example.org\r\n"
2678 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322679
bnc691fda62016-08-12 00:43:162680 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182681 // be issuing -- the final header line contains the credentials.
2682 MockWrite(ASYNC, 6,
2683 "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"),
2687 };
[email protected]2d2697f92009-02-18 21:00:322688
mmenkecc2298e2015-12-07 18:20:182689 MockRead data_reads[] = {
2690 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2691 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2692 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2693 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2694 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322695
mmenkecc2298e2015-12-07 18:20:182696 // Lastly, the server responds with the actual content.
2697 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2698 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2699 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2700 MockRead(ASYNC, 10, "Hello"),
2701 };
[email protected]2d2697f92009-02-18 21:00:322702
mmenkecc2298e2015-12-07 18:20:182703 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2704 arraysize(data_writes));
2705 data.set_busy_before_sync_reads(true);
2706 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462707
mmenkecc2298e2015-12-07 18:20:182708 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322709
bnc691fda62016-08-12 00:43:162710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202711 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012712 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322713
mmenkecc2298e2015-12-07 18:20:182714 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162715 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182716 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322717
bnc691fda62016-08-12 00:43:162718 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182719 ASSERT_TRUE(response);
2720 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322721
mmenkecc2298e2015-12-07 18:20:182722 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252723
bnc691fda62016-08-12 00:43:162724 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2725 callback2.callback());
robpercival214763f2016-07-01 23:27:012726 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322727
mmenkecc2298e2015-12-07 18:20:182728 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162729 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182730 TestLoadTimingReused(load_timing_info2);
2731 // The load timing after restart should have the same socket ID, and times
2732 // those of the first load timing.
2733 EXPECT_LE(load_timing_info1.receive_headers_end,
2734 load_timing_info2.send_start);
2735 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322736
bnc691fda62016-08-12 00:43:162737 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182738 ASSERT_TRUE(response);
2739 EXPECT_FALSE(response->auth_challenge);
2740 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322741
mmenkecc2298e2015-12-07 18:20:182742 std::string response_data;
bnc691fda62016-08-12 00:43:162743 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322744
mmenkecc2298e2015-12-07 18:20:182745 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162746 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182747 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162748 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182749 }
[email protected]2d2697f92009-02-18 21:00:322750}
2751
2752// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2753// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012754TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422755 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322756 request.method = "GET";
bncce36dca22015-04-21 22:11:232757 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322758
danakj1fd259a02016-04-16 03:17:092759 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272760
[email protected]2d2697f92009-02-18 21:00:322761 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162762 MockWrite("GET / HTTP/1.1\r\n"
2763 "Host: www.example.org\r\n"
2764 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322765
bnc691fda62016-08-12 00:43:162766 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232767 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162768 MockWrite("GET / HTTP/1.1\r\n"
2769 "Host: www.example.org\r\n"
2770 "Connection: keep-alive\r\n"
2771 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322772 };
2773
[email protected]2d2697f92009-02-18 21:00:322774 MockRead data_reads1[] = {
2775 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2776 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312777 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322778
2779 // Lastly, the server responds with the actual content.
2780 MockRead("HTTP/1.1 200 OK\r\n"),
2781 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502782 MockRead("Content-Length: 5\r\n\r\n"),
2783 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322784 };
2785
[email protected]2d0a4f92011-05-05 16:38:462786 // An incorrect reconnect would cause this to be read.
2787 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062788 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462789 };
2790
[email protected]31a2bfe2010-02-09 08:03:392791 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2792 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462793 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2794 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072795 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2796 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322797
[email protected]49639fa2011-12-20 23:22:412798 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322799
bnc691fda62016-08-12 00:43:162800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202801 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322803
2804 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012805 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322806
bnc691fda62016-08-12 00:43:162807 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522808 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042809 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322810
[email protected]49639fa2011-12-20 23:22:412811 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322812
bnc691fda62016-08-12 00:43:162813 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322815
2816 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012817 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322818
bnc691fda62016-08-12 00:43:162819 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522820 ASSERT_TRUE(response);
2821 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502822 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322823}
2824
2825// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2826// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012827TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422828 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322829 request.method = "GET";
bncce36dca22015-04-21 22:11:232830 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322831
danakj1fd259a02016-04-16 03:17:092832 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272833
[email protected]2d2697f92009-02-18 21:00:322834 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162835 MockWrite("GET / HTTP/1.1\r\n"
2836 "Host: www.example.org\r\n"
2837 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322838
bnc691fda62016-08-12 00:43:162839 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232840 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162841 MockWrite("GET / HTTP/1.1\r\n"
2842 "Host: www.example.org\r\n"
2843 "Connection: keep-alive\r\n"
2844 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322845 };
2846
2847 // Respond with 5 kb of response body.
2848 std::string large_body_string("Unauthorized");
2849 large_body_string.append(5 * 1024, ' ');
2850 large_body_string.append("\r\n");
2851
2852 MockRead data_reads1[] = {
2853 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2854 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2855 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2856 // 5134 = 12 + 5 * 1024 + 2
2857 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062858 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322859
2860 // Lastly, the server responds with the actual content.
2861 MockRead("HTTP/1.1 200 OK\r\n"),
2862 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502863 MockRead("Content-Length: 5\r\n\r\n"),
2864 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322865 };
2866
[email protected]2d0a4f92011-05-05 16:38:462867 // An incorrect reconnect would cause this to be read.
2868 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062869 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462870 };
2871
[email protected]31a2bfe2010-02-09 08:03:392872 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2873 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462874 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2875 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072876 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2877 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322878
[email protected]49639fa2011-12-20 23:22:412879 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322880
bnc691fda62016-08-12 00:43:162881 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202882 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322884
2885 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012886 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322887
bnc691fda62016-08-12 00:43:162888 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522889 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042890 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322891
[email protected]49639fa2011-12-20 23:22:412892 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322893
bnc691fda62016-08-12 00:43:162894 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322896
2897 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012898 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322899
bnc691fda62016-08-12 00:43:162900 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522901 ASSERT_TRUE(response);
2902 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502903 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322904}
2905
2906// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312907// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012908TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312909 HttpRequestInfo request;
2910 request.method = "GET";
bncce36dca22015-04-21 22:11:232911 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312912
danakj1fd259a02016-04-16 03:17:092913 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272914
[email protected]11203f012009-11-12 23:02:312915 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232916 MockWrite(
2917 "GET / HTTP/1.1\r\n"
2918 "Host: www.example.org\r\n"
2919 "Connection: keep-alive\r\n\r\n"),
2920 // This simulates the seemingly successful write to a closed connection
2921 // if the bug is not fixed.
2922 MockWrite(
2923 "GET / HTTP/1.1\r\n"
2924 "Host: www.example.org\r\n"
2925 "Connection: keep-alive\r\n"
2926 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312927 };
2928
2929 MockRead data_reads1[] = {
2930 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2931 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2932 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2933 MockRead("Content-Length: 14\r\n\r\n"),
2934 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062935 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312936 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062937 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312938 };
2939
bnc691fda62016-08-12 00:43:162940 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312941 // be issuing -- the final header line contains the credentials.
2942 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232943 MockWrite(
2944 "GET / HTTP/1.1\r\n"
2945 "Host: www.example.org\r\n"
2946 "Connection: keep-alive\r\n"
2947 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312948 };
2949
2950 // Lastly, the server responds with the actual content.
2951 MockRead data_reads2[] = {
2952 MockRead("HTTP/1.1 200 OK\r\n"),
2953 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502954 MockRead("Content-Length: 5\r\n\r\n"),
2955 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312956 };
2957
[email protected]31a2bfe2010-02-09 08:03:392958 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2959 data_writes1, arraysize(data_writes1));
2960 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2961 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072962 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2963 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312964
[email protected]49639fa2011-12-20 23:22:412965 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312966
bnc691fda62016-08-12 00:43:162967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202968 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012969 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312970
2971 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012972 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312973
bnc691fda62016-08-12 00:43:162974 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522975 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042976 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312977
[email protected]49639fa2011-12-20 23:22:412978 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312979
bnc691fda62016-08-12 00:43:162980 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012981 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312982
2983 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012984 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312985
bnc691fda62016-08-12 00:43:162986 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522987 ASSERT_TRUE(response);
2988 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502989 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312990}
2991
[email protected]394816e92010-08-03 07:38:592992// Test the request-challenge-retry sequence for basic auth, over a connection
2993// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012994TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012995 HttpRequestInfo request;
2996 request.method = "GET";
bncce36dca22015-04-21 22:11:232997 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012998 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292999 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013000
3001 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033002 session_deps_.proxy_service =
3003 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513004 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013005 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013007
3008 // Since we have proxy, should try to establish tunnel.
3009 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543010 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173011 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543012 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013013 };
3014
mmenkee71e15332015-10-07 16:39:543015 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013016 // connection.
3017 MockRead data_reads1[] = {
3018 // No credentials.
3019 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3020 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543021 };
ttuttle34f63b52015-03-05 04:33:013022
mmenkee71e15332015-10-07 16:39:543023 // Since the first connection couldn't be reused, need to establish another
3024 // once given credentials.
3025 MockWrite data_writes2[] = {
3026 // After calling trans->RestartWithAuth(), this is the request we should
3027 // be issuing -- the final header line contains the credentials.
3028 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173029 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543030 "Proxy-Connection: keep-alive\r\n"
3031 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3032
3033 MockWrite("GET / HTTP/1.1\r\n"
3034 "Host: www.example.org\r\n"
3035 "Connection: keep-alive\r\n\r\n"),
3036 };
3037
3038 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013039 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3040
3041 MockRead("HTTP/1.1 200 OK\r\n"),
3042 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3043 MockRead("Content-Length: 5\r\n\r\n"),
3044 MockRead(SYNCHRONOUS, "hello"),
3045 };
3046
3047 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3048 data_writes1, arraysize(data_writes1));
3049 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543050 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3051 data_writes2, arraysize(data_writes2));
3052 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013053 SSLSocketDataProvider ssl(ASYNC, OK);
3054 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3055
3056 TestCompletionCallback callback1;
3057
bnc87dcefc2017-05-25 12:47:583058 auto trans =
3059 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013060
3061 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013063
3064 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013065 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463066 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013067 log.GetEntries(&entries);
3068 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003069 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3070 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013071 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003072 entries, pos,
3073 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3074 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013075
3076 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523077 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013078 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523079 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013080 EXPECT_EQ(407, response->headers->response_code());
3081 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3082 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3083
3084 LoadTimingInfo load_timing_info;
3085 // CONNECT requests and responses are handled at the connect job level, so
3086 // the transaction does not yet have a connection.
3087 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3088
3089 TestCompletionCallback callback2;
3090
3091 rv =
3092 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013094
3095 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013096 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013097
3098 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523099 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013100
3101 EXPECT_TRUE(response->headers->IsKeepAlive());
3102 EXPECT_EQ(200, response->headers->response_code());
3103 EXPECT_EQ(5, response->headers->GetContentLength());
3104 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3105
3106 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523107 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013108
3109 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3110 TestLoadTimingNotReusedWithPac(load_timing_info,
3111 CONNECT_TIMING_HAS_SSL_TIMES);
3112
3113 trans.reset();
3114 session->CloseAllConnections();
3115}
3116
3117// Test the request-challenge-retry sequence for basic auth, over a connection
3118// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013119TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593120 HttpRequestInfo request;
3121 request.method = "GET";
bncce36dca22015-04-21 22:11:233122 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593123 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293124 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593125
[email protected]cb9bf6ca2011-01-28 13:15:273126 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033127 session_deps_.proxy_service =
3128 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513129 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073130 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273132
[email protected]394816e92010-08-03 07:38:593133 // Since we have proxy, should try to establish tunnel.
3134 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543135 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173136 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543137 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113138 };
3139
mmenkee71e15332015-10-07 16:39:543140 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083141 // connection.
3142 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543143 // No credentials.
3144 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3145 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3146 MockRead("Proxy-Connection: close\r\n\r\n"),
3147 };
mmenkee0b5c882015-08-26 20:29:113148
mmenkee71e15332015-10-07 16:39:543149 MockWrite data_writes2[] = {
3150 // After calling trans->RestartWithAuth(), this is the request we should
3151 // be issuing -- the final header line contains the credentials.
3152 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173153 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543154 "Proxy-Connection: keep-alive\r\n"
3155 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083156
mmenkee71e15332015-10-07 16:39:543157 MockWrite("GET / HTTP/1.1\r\n"
3158 "Host: www.example.org\r\n"
3159 "Connection: keep-alive\r\n\r\n"),
3160 };
3161
3162 MockRead data_reads2[] = {
3163 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3164
3165 MockRead("HTTP/1.1 200 OK\r\n"),
3166 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3167 MockRead("Content-Length: 5\r\n\r\n"),
3168 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593169 };
3170
3171 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3172 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073173 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543174 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3175 data_writes2, arraysize(data_writes2));
3176 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063177 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073178 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593179
[email protected]49639fa2011-12-20 23:22:413180 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593181
bnc87dcefc2017-05-25 12:47:583182 auto trans =
3183 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503184
[email protected]49639fa2011-12-20 23:22:413185 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013186 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593187
3188 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013189 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463190 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403191 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593192 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003193 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3194 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593195 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403196 entries, pos,
mikecirone8b85c432016-09-08 19:11:003197 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3198 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593199
3200 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523201 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013202 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523203 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593204 EXPECT_EQ(407, response->headers->response_code());
3205 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043206 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593207
[email protected]029c83b62013-01-24 05:28:203208 LoadTimingInfo load_timing_info;
3209 // CONNECT requests and responses are handled at the connect job level, so
3210 // the transaction does not yet have a connection.
3211 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3212
[email protected]49639fa2011-12-20 23:22:413213 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593214
[email protected]49639fa2011-12-20 23:22:413215 rv = trans->RestartWithAuth(
3216 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593218
3219 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013220 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593221
3222 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523223 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593224
3225 EXPECT_TRUE(response->headers->IsKeepAlive());
3226 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503227 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593228 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3229
3230 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523231 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503232
[email protected]029c83b62013-01-24 05:28:203233 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3234 TestLoadTimingNotReusedWithPac(load_timing_info,
3235 CONNECT_TIMING_HAS_SSL_TIMES);
3236
[email protected]0b0bf032010-09-21 18:08:503237 trans.reset();
[email protected]102e27c2011-02-23 01:01:313238 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593239}
3240
[email protected]11203f012009-11-12 23:02:313241// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013242// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013243TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233244 // On the second pass, the body read of the auth challenge is synchronous, so
3245 // IsConnectedAndIdle returns false. The socket should still be drained and
3246 // reused. See http://crbug.com/544255.
3247 for (int i = 0; i < 2; ++i) {
3248 HttpRequestInfo request;
3249 request.method = "GET";
3250 request.url = GURL("https://www.example.org/");
3251 // Ensure that proxy authentication is attempted even
3252 // when the no authentication data flag is set.
3253 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013254
mmenked39192ee2015-12-09 00:57:233255 // Configure against proxy server "myproxy:70".
3256 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3257 BoundTestNetLog log;
3258 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013260
bnc691fda62016-08-12 00:43:163261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013262
mmenked39192ee2015-12-09 00:57:233263 // Since we have proxy, should try to establish tunnel.
3264 MockWrite data_writes1[] = {
3265 MockWrite(ASYNC, 0,
3266 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3267 "Host: www.example.org:443\r\n"
3268 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013269
bnc691fda62016-08-12 00:43:163270 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233271 // be issuing -- the final header line contains the credentials.
3272 MockWrite(ASYNC, 3,
3273 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3274 "Host: www.example.org:443\r\n"
3275 "Proxy-Connection: keep-alive\r\n"
3276 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3277 };
ttuttle34f63b52015-03-05 04:33:013278
mmenked39192ee2015-12-09 00:57:233279 // The proxy responds to the connect with a 407, using a persistent
3280 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3281 MockRead data_reads1[] = {
3282 // No credentials.
3283 MockRead(ASYNC, 1,
3284 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3285 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3286 "Proxy-Connection: keep-alive\r\n"
3287 "Content-Length: 10\r\n\r\n"),
3288 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013289
mmenked39192ee2015-12-09 00:57:233290 // Wrong credentials (wrong password).
3291 MockRead(ASYNC, 4,
3292 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3293 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3294 "Proxy-Connection: keep-alive\r\n"
3295 "Content-Length: 10\r\n\r\n"),
3296 // No response body because the test stops reading here.
3297 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3298 };
ttuttle34f63b52015-03-05 04:33:013299
mmenked39192ee2015-12-09 00:57:233300 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3301 arraysize(data_writes1));
3302 data1.set_busy_before_sync_reads(true);
3303 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013304
mmenked39192ee2015-12-09 00:57:233305 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013306
bnc691fda62016-08-12 00:43:163307 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013308 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013309
mmenked39192ee2015-12-09 00:57:233310 TestNetLogEntry::List entries;
3311 log.GetEntries(&entries);
3312 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003313 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3314 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233315 ExpectLogContainsSomewhere(
3316 entries, pos,
mikecirone8b85c432016-09-08 19:11:003317 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3318 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013319
bnc691fda62016-08-12 00:43:163320 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233321 ASSERT_TRUE(response);
3322 ASSERT_TRUE(response->headers);
3323 EXPECT_TRUE(response->headers->IsKeepAlive());
3324 EXPECT_EQ(407, response->headers->response_code());
3325 EXPECT_EQ(10, response->headers->GetContentLength());
3326 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3327 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013328
mmenked39192ee2015-12-09 00:57:233329 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013330
mmenked39192ee2015-12-09 00:57:233331 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163332 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3333 callback2.callback());
robpercival214763f2016-07-01 23:27:013334 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013335
bnc691fda62016-08-12 00:43:163336 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233337 ASSERT_TRUE(response);
3338 ASSERT_TRUE(response->headers);
3339 EXPECT_TRUE(response->headers->IsKeepAlive());
3340 EXPECT_EQ(407, response->headers->response_code());
3341 EXPECT_EQ(10, response->headers->GetContentLength());
3342 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3343 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013344
mmenked39192ee2015-12-09 00:57:233345 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3346 // out of scope.
3347 session->CloseAllConnections();
3348 }
ttuttle34f63b52015-03-05 04:33:013349}
3350
3351// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3352// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013353TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233354 // On the second pass, the body read of the auth challenge is synchronous, so
3355 // IsConnectedAndIdle returns false. The socket should still be drained and
3356 // reused. See http://crbug.com/544255.
3357 for (int i = 0; i < 2; ++i) {
3358 HttpRequestInfo request;
3359 request.method = "GET";
3360 request.url = GURL("https://www.example.org/");
3361 // Ensure that proxy authentication is attempted even
3362 // when the no authentication data flag is set.
3363 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3364
3365 // Configure against proxy server "myproxy:70".
3366 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3367 BoundTestNetLog log;
3368 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093369 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233370
bnc691fda62016-08-12 00:43:163371 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233372
3373 // Since we have proxy, should try to establish tunnel.
3374 MockWrite data_writes1[] = {
3375 MockWrite(ASYNC, 0,
3376 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3377 "Host: www.example.org:443\r\n"
3378 "Proxy-Connection: keep-alive\r\n\r\n"),
3379
bnc691fda62016-08-12 00:43:163380 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233381 // be issuing -- the final header line contains the credentials.
3382 MockWrite(ASYNC, 3,
3383 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3384 "Host: www.example.org:443\r\n"
3385 "Proxy-Connection: keep-alive\r\n"
3386 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3387 };
3388
3389 // The proxy responds to the connect with a 407, using a persistent
3390 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3391 MockRead data_reads1[] = {
3392 // No credentials.
3393 MockRead(ASYNC, 1,
3394 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3395 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3396 "Content-Length: 10\r\n\r\n"),
3397 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3398
3399 // Wrong credentials (wrong password).
3400 MockRead(ASYNC, 4,
3401 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3402 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3403 "Content-Length: 10\r\n\r\n"),
3404 // No response body because the test stops reading here.
3405 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3406 };
3407
3408 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3409 arraysize(data_writes1));
3410 data1.set_busy_before_sync_reads(true);
3411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3412
3413 TestCompletionCallback callback1;
3414
bnc691fda62016-08-12 00:43:163415 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013416 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233417
3418 TestNetLogEntry::List entries;
3419 log.GetEntries(&entries);
3420 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003421 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3422 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233423 ExpectLogContainsSomewhere(
3424 entries, pos,
mikecirone8b85c432016-09-08 19:11:003425 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3426 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233427
bnc691fda62016-08-12 00:43:163428 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233429 ASSERT_TRUE(response);
3430 ASSERT_TRUE(response->headers);
3431 EXPECT_TRUE(response->headers->IsKeepAlive());
3432 EXPECT_EQ(407, response->headers->response_code());
3433 EXPECT_EQ(10, response->headers->GetContentLength());
3434 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3435 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3436
3437 TestCompletionCallback callback2;
3438
3439 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163440 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3441 callback2.callback());
robpercival214763f2016-07-01 23:27:013442 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233443
bnc691fda62016-08-12 00:43:163444 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233445 ASSERT_TRUE(response);
3446 ASSERT_TRUE(response->headers);
3447 EXPECT_TRUE(response->headers->IsKeepAlive());
3448 EXPECT_EQ(407, response->headers->response_code());
3449 EXPECT_EQ(10, response->headers->GetContentLength());
3450 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3451 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3452
3453 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3454 // out of scope.
3455 session->CloseAllConnections();
3456 }
3457}
3458
3459// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3460// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3461// the case the server sends extra data on the original socket, so it can't be
3462// reused.
bncd16676a2016-07-20 16:23:013463TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273464 HttpRequestInfo request;
3465 request.method = "GET";
bncce36dca22015-04-21 22:11:233466 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273467 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293468 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273469
[email protected]2d2697f92009-02-18 21:00:323470 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233471 session_deps_.proxy_service =
3472 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513473 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073474 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323476
[email protected]2d2697f92009-02-18 21:00:323477 // Since we have proxy, should try to establish tunnel.
3478 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233479 MockWrite(ASYNC, 0,
3480 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173481 "Host: www.example.org:443\r\n"
3482 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233483 };
[email protected]2d2697f92009-02-18 21:00:323484
mmenked39192ee2015-12-09 00:57:233485 // The proxy responds to the connect with a 407, using a persistent, but sends
3486 // extra data, so the socket cannot be reused.
3487 MockRead data_reads1[] = {
3488 // No credentials.
3489 MockRead(ASYNC, 1,
3490 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3491 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3492 "Content-Length: 10\r\n\r\n"),
3493 MockRead(SYNCHRONOUS, 2, "0123456789"),
3494 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3495 };
3496
3497 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233498 // After calling trans->RestartWithAuth(), this is the request we should
3499 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233500 MockWrite(ASYNC, 0,
3501 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173502 "Host: www.example.org:443\r\n"
3503 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233504 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3505
3506 MockWrite(ASYNC, 2,
3507 "GET / HTTP/1.1\r\n"
3508 "Host: www.example.org\r\n"
3509 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323510 };
3511
mmenked39192ee2015-12-09 00:57:233512 MockRead data_reads2[] = {
3513 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323514
mmenked39192ee2015-12-09 00:57:233515 MockRead(ASYNC, 3,
3516 "HTTP/1.1 200 OK\r\n"
3517 "Content-Type: text/html; charset=iso-8859-1\r\n"
3518 "Content-Length: 5\r\n\r\n"),
3519 // No response body because the test stops reading here.
3520 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323521 };
3522
mmenked39192ee2015-12-09 00:57:233523 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3524 arraysize(data_writes1));
3525 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073526 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233527 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3528 arraysize(data_writes2));
3529 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3530 SSLSocketDataProvider ssl(ASYNC, OK);
3531 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323532
[email protected]49639fa2011-12-20 23:22:413533 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323534
bnc87dcefc2017-05-25 12:47:583535 auto trans =
3536 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323537
mmenked39192ee2015-12-09 00:57:233538 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013539 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233540
mmenke43758e62015-05-04 21:09:463541 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403542 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393543 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003544 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3545 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393546 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403547 entries, pos,
mikecirone8b85c432016-09-08 19:11:003548 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3549 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323550
[email protected]1c773ea12009-04-28 19:58:423551 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243552 ASSERT_TRUE(response);
3553 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323554 EXPECT_TRUE(response->headers->IsKeepAlive());
3555 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423556 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043557 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323558
mmenked39192ee2015-12-09 00:57:233559 LoadTimingInfo load_timing_info;
3560 // CONNECT requests and responses are handled at the connect job level, so
3561 // the transaction does not yet have a connection.
3562 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3563
[email protected]49639fa2011-12-20 23:22:413564 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323565
mmenked39192ee2015-12-09 00:57:233566 rv =
3567 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013568 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323569
[email protected]2d2697f92009-02-18 21:00:323570 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233571 EXPECT_EQ(200, response->headers->response_code());
3572 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423573 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133574
mmenked39192ee2015-12-09 00:57:233575 // The password prompt info should not be set.
3576 EXPECT_FALSE(response->auth_challenge);
3577
3578 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3579 TestLoadTimingNotReusedWithPac(load_timing_info,
3580 CONNECT_TIMING_HAS_SSL_TIMES);
3581
3582 trans.reset();
[email protected]102e27c2011-02-23 01:01:313583 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323584}
3585
mmenkee71e15332015-10-07 16:39:543586// Test the case a proxy closes a socket while the challenge body is being
3587// drained.
bncd16676a2016-07-20 16:23:013588TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543589 HttpRequestInfo request;
3590 request.method = "GET";
3591 request.url = GURL("https://www.example.org/");
3592 // Ensure that proxy authentication is attempted even
3593 // when the no authentication data flag is set.
3594 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3595
3596 // Configure against proxy server "myproxy:70".
3597 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093598 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543599
bnc691fda62016-08-12 00:43:163600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543601
3602 // Since we have proxy, should try to establish tunnel.
3603 MockWrite data_writes1[] = {
3604 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173605 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543606 "Proxy-Connection: keep-alive\r\n\r\n"),
3607 };
3608
3609 // The proxy responds to the connect with a 407, using a persistent
3610 // connection.
3611 MockRead data_reads1[] = {
3612 // No credentials.
3613 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3614 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3615 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3616 // Server hands up in the middle of the body.
3617 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3618 };
3619
3620 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163621 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543622 // be issuing -- the final header line contains the credentials.
3623 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173624 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543625 "Proxy-Connection: keep-alive\r\n"
3626 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3627
3628 MockWrite("GET / HTTP/1.1\r\n"
3629 "Host: www.example.org\r\n"
3630 "Connection: keep-alive\r\n\r\n"),
3631 };
3632
3633 MockRead data_reads2[] = {
3634 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3635
3636 MockRead("HTTP/1.1 200 OK\r\n"),
3637 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3638 MockRead("Content-Length: 5\r\n\r\n"),
3639 MockRead(SYNCHRONOUS, "hello"),
3640 };
3641
3642 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3643 data_writes1, arraysize(data_writes1));
3644 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3645 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3646 data_writes2, arraysize(data_writes2));
3647 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3648 SSLSocketDataProvider ssl(ASYNC, OK);
3649 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3650
3651 TestCompletionCallback callback;
3652
tfarina42834112016-09-22 13:38:203653 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013654 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543655
bnc691fda62016-08-12 00:43:163656 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543657 ASSERT_TRUE(response);
3658 ASSERT_TRUE(response->headers);
3659 EXPECT_TRUE(response->headers->IsKeepAlive());
3660 EXPECT_EQ(407, response->headers->response_code());
3661 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3662
bnc691fda62016-08-12 00:43:163663 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013664 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543665
bnc691fda62016-08-12 00:43:163666 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543667 ASSERT_TRUE(response);
3668 ASSERT_TRUE(response->headers);
3669 EXPECT_TRUE(response->headers->IsKeepAlive());
3670 EXPECT_EQ(200, response->headers->response_code());
3671 std::string body;
bnc691fda62016-08-12 00:43:163672 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543673 EXPECT_EQ("hello", body);
3674}
3675
[email protected]a8e9b162009-03-12 00:06:443676// Test that we don't read the response body when we fail to establish a tunnel,
3677// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013678TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273679 HttpRequestInfo request;
3680 request.method = "GET";
bncce36dca22015-04-21 22:11:233681 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273682
[email protected]a8e9b162009-03-12 00:06:443683 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033684 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443685
danakj1fd259a02016-04-16 03:17:093686 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443687
bnc691fda62016-08-12 00:43:163688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443689
[email protected]a8e9b162009-03-12 00:06:443690 // Since we have proxy, should try to establish tunnel.
3691 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173692 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3693 "Host: www.example.org:443\r\n"
3694 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443695 };
3696
3697 // The proxy responds to the connect with a 407.
3698 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243699 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3700 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3701 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233702 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243703 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443704 };
3705
[email protected]31a2bfe2010-02-09 08:03:393706 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3707 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073708 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443709
[email protected]49639fa2011-12-20 23:22:413710 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443711
tfarina42834112016-09-22 13:38:203712 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013713 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443714
3715 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013716 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443717
bnc691fda62016-08-12 00:43:163718 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243719 ASSERT_TRUE(response);
3720 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443721 EXPECT_TRUE(response->headers->IsKeepAlive());
3722 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423723 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443724
3725 std::string response_data;
bnc691fda62016-08-12 00:43:163726 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013727 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183728
3729 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313730 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443731}
3732
ttuttle7933c112015-01-06 00:55:243733// Test that we don't pass extraneous headers from the proxy's response to the
3734// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013735TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243736 HttpRequestInfo request;
3737 request.method = "GET";
bncce36dca22015-04-21 22:11:233738 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243739
3740 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033741 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243742
danakj1fd259a02016-04-16 03:17:093743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243744
bnc691fda62016-08-12 00:43:163745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243746
3747 // Since we have proxy, should try to establish tunnel.
3748 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173749 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3750 "Host: www.example.org:443\r\n"
3751 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243752 };
3753
3754 // The proxy responds to the connect with a 407.
3755 MockRead data_reads[] = {
3756 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3757 MockRead("X-Foo: bar\r\n"),
3758 MockRead("Set-Cookie: foo=bar\r\n"),
3759 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3760 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233761 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243762 };
3763
3764 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3765 arraysize(data_writes));
3766 session_deps_.socket_factory->AddSocketDataProvider(&data);
3767
3768 TestCompletionCallback callback;
3769
tfarina42834112016-09-22 13:38:203770 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243772
3773 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013774 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243775
bnc691fda62016-08-12 00:43:163776 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243777 ASSERT_TRUE(response);
3778 ASSERT_TRUE(response->headers);
3779 EXPECT_TRUE(response->headers->IsKeepAlive());
3780 EXPECT_EQ(407, response->headers->response_code());
3781 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3782 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3783 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3784
3785 std::string response_data;
bnc691fda62016-08-12 00:43:163786 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013787 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243788
3789 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3790 session->CloseAllConnections();
3791}
3792
[email protected]8fdbcd22010-05-05 02:54:523793// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3794// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013795TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523796 HttpRequestInfo request;
3797 request.method = "GET";
bncce36dca22015-04-21 22:11:233798 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523799
[email protected]cb9bf6ca2011-01-28 13:15:273800 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273803
[email protected]8fdbcd22010-05-05 02:54:523804 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233805 MockWrite(
3806 "GET / HTTP/1.1\r\n"
3807 "Host: www.example.org\r\n"
3808 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523809 };
3810
3811 MockRead data_reads1[] = {
3812 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3813 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3814 // Large content-length -- won't matter, as connection will be reset.
3815 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063816 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523817 };
3818
3819 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3820 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073821 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523822
[email protected]49639fa2011-12-20 23:22:413823 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523824
tfarina42834112016-09-22 13:38:203825 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523827
3828 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013829 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523830}
3831
[email protected]7a67a8152010-11-05 18:31:103832// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3833// through a non-authenticating proxy. The request should fail with
3834// ERR_UNEXPECTED_PROXY_AUTH.
3835// Note that it is impossible to detect if an HTTP server returns a 407 through
3836// a non-authenticating proxy - there is nothing to indicate whether the
3837// response came from the proxy or the server, so it is treated as if the proxy
3838// issued the challenge.
bncd16676a2016-07-20 16:23:013839TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273840 HttpRequestInfo request;
3841 request.method = "GET";
bncce36dca22015-04-21 22:11:233842 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273843
rdsmith82957ad2015-09-16 19:42:033844 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513845 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073846 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103848
[email protected]7a67a8152010-11-05 18:31:103849 // Since we have proxy, should try to establish tunnel.
3850 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173851 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3852 "Host: www.example.org:443\r\n"
3853 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103854
rsleevidb16bb02015-11-12 23:47:173855 MockWrite("GET / HTTP/1.1\r\n"
3856 "Host: www.example.org\r\n"
3857 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103858 };
3859
3860 MockRead data_reads1[] = {
3861 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3862
3863 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3864 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3865 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063866 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103867 };
3868
3869 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3870 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063872 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103874
[email protected]49639fa2011-12-20 23:22:413875 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103876
bnc691fda62016-08-12 00:43:163877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103878
bnc691fda62016-08-12 00:43:163879 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103881
3882 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013883 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463884 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403885 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103886 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003887 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3888 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103889 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403890 entries, pos,
mikecirone8b85c432016-09-08 19:11:003891 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3892 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103893}
[email protected]2df19bb2010-08-25 20:13:463894
mmenke2a1781d2015-10-07 19:25:333895// Test a proxy auth scheme that allows default credentials and a proxy server
3896// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013897TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333898 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3899 HttpRequestInfo request;
3900 request.method = "GET";
3901 request.url = GURL("https://www.example.org/");
3902
3903 // Configure against proxy server "myproxy:70".
3904 session_deps_.proxy_service =
3905 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3906
bnc87dcefc2017-05-25 12:47:583907 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333908 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583909 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333910 mock_handler->set_allows_default_credentials(true);
3911 auth_handler_factory->AddMockHandler(mock_handler.release(),
3912 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483913 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333914
3915 // Add NetLog just so can verify load timing information gets a NetLog ID.
3916 NetLog net_log;
3917 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093918 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333919
3920 // Since we have proxy, should try to establish tunnel.
3921 MockWrite data_writes1[] = {
3922 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173923 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333924 "Proxy-Connection: keep-alive\r\n\r\n"),
3925 };
3926
3927 // The proxy responds to the connect with a 407, using a non-persistent
3928 // connection.
3929 MockRead data_reads1[] = {
3930 // No credentials.
3931 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3932 MockRead("Proxy-Authenticate: Mock\r\n"),
3933 MockRead("Proxy-Connection: close\r\n\r\n"),
3934 };
3935
3936 // Since the first connection couldn't be reused, need to establish another
3937 // once given credentials.
3938 MockWrite data_writes2[] = {
3939 // After calling trans->RestartWithAuth(), this is the request we should
3940 // be issuing -- the final header line contains the credentials.
3941 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173942 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333943 "Proxy-Connection: keep-alive\r\n"
3944 "Proxy-Authorization: auth_token\r\n\r\n"),
3945
3946 MockWrite("GET / HTTP/1.1\r\n"
3947 "Host: www.example.org\r\n"
3948 "Connection: keep-alive\r\n\r\n"),
3949 };
3950
3951 MockRead data_reads2[] = {
3952 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3953
3954 MockRead("HTTP/1.1 200 OK\r\n"),
3955 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3956 MockRead("Content-Length: 5\r\n\r\n"),
3957 MockRead(SYNCHRONOUS, "hello"),
3958 };
3959
3960 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3961 data_writes1, arraysize(data_writes1));
3962 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3963 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3964 data_writes2, arraysize(data_writes2));
3965 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3966 SSLSocketDataProvider ssl(ASYNC, OK);
3967 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3968
bnc87dcefc2017-05-25 12:47:583969 auto trans =
3970 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333971
3972 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203973 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013974 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333975
3976 const HttpResponseInfo* response = trans->GetResponseInfo();
3977 ASSERT_TRUE(response);
3978 ASSERT_TRUE(response->headers);
3979 EXPECT_FALSE(response->headers->IsKeepAlive());
3980 EXPECT_EQ(407, response->headers->response_code());
3981 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3982 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523983 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333984
3985 LoadTimingInfo load_timing_info;
3986 // CONNECT requests and responses are handled at the connect job level, so
3987 // the transaction does not yet have a connection.
3988 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3989
3990 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013991 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333992 response = trans->GetResponseInfo();
3993 ASSERT_TRUE(response);
3994 ASSERT_TRUE(response->headers);
3995 EXPECT_TRUE(response->headers->IsKeepAlive());
3996 EXPECT_EQ(200, response->headers->response_code());
3997 EXPECT_EQ(5, response->headers->GetContentLength());
3998 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3999
4000 // The password prompt info should not be set.
4001 EXPECT_FALSE(response->auth_challenge);
4002
4003 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4004 TestLoadTimingNotReusedWithPac(load_timing_info,
4005 CONNECT_TIMING_HAS_SSL_TIMES);
4006
4007 trans.reset();
4008 session->CloseAllConnections();
4009}
4010
4011// Test a proxy auth scheme that allows default credentials and a proxy server
4012// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014013TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334014 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4015 HttpRequestInfo request;
4016 request.method = "GET";
4017 request.url = GURL("https://www.example.org/");
4018
4019 // Configure against proxy server "myproxy:70".
4020 session_deps_.proxy_service =
4021 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4022
bnc87dcefc2017-05-25 12:47:584023 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334024 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584025 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334026 mock_handler->set_allows_default_credentials(true);
4027 auth_handler_factory->AddMockHandler(mock_handler.release(),
4028 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484029 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334030
4031 // Add NetLog just so can verify load timing information gets a NetLog ID.
4032 NetLog net_log;
4033 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094034 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334035
4036 // Should try to establish tunnel.
4037 MockWrite data_writes1[] = {
4038 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174039 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334040 "Proxy-Connection: keep-alive\r\n\r\n"),
4041
4042 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174043 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334044 "Proxy-Connection: keep-alive\r\n"
4045 "Proxy-Authorization: auth_token\r\n\r\n"),
4046 };
4047
4048 // The proxy responds to the connect with a 407, using a non-persistent
4049 // connection.
4050 MockRead data_reads1[] = {
4051 // No credentials.
4052 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4053 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4054 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4055 };
4056
4057 // Since the first connection was closed, need to establish another once given
4058 // credentials.
4059 MockWrite data_writes2[] = {
4060 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174061 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334062 "Proxy-Connection: keep-alive\r\n"
4063 "Proxy-Authorization: auth_token\r\n\r\n"),
4064
4065 MockWrite("GET / HTTP/1.1\r\n"
4066 "Host: www.example.org\r\n"
4067 "Connection: keep-alive\r\n\r\n"),
4068 };
4069
4070 MockRead data_reads2[] = {
4071 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4072
4073 MockRead("HTTP/1.1 200 OK\r\n"),
4074 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4075 MockRead("Content-Length: 5\r\n\r\n"),
4076 MockRead(SYNCHRONOUS, "hello"),
4077 };
4078
4079 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4080 data_writes1, arraysize(data_writes1));
4081 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4082 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4083 data_writes2, arraysize(data_writes2));
4084 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4085 SSLSocketDataProvider ssl(ASYNC, OK);
4086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4087
bnc87dcefc2017-05-25 12:47:584088 auto trans =
4089 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334090
4091 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204092 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014093 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334094
4095 const HttpResponseInfo* response = trans->GetResponseInfo();
4096 ASSERT_TRUE(response);
4097 ASSERT_TRUE(response->headers);
4098 EXPECT_TRUE(response->headers->IsKeepAlive());
4099 EXPECT_EQ(407, response->headers->response_code());
4100 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4101 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4102 EXPECT_FALSE(response->auth_challenge);
4103
4104 LoadTimingInfo load_timing_info;
4105 // CONNECT requests and responses are handled at the connect job level, so
4106 // the transaction does not yet have a connection.
4107 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4108
4109 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014110 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334111
4112 response = trans->GetResponseInfo();
4113 ASSERT_TRUE(response);
4114 ASSERT_TRUE(response->headers);
4115 EXPECT_TRUE(response->headers->IsKeepAlive());
4116 EXPECT_EQ(200, response->headers->response_code());
4117 EXPECT_EQ(5, response->headers->GetContentLength());
4118 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4119
4120 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524121 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334122
4123 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4124 TestLoadTimingNotReusedWithPac(load_timing_info,
4125 CONNECT_TIMING_HAS_SSL_TIMES);
4126
4127 trans.reset();
4128 session->CloseAllConnections();
4129}
4130
4131// Test a proxy auth scheme that allows default credentials and a proxy server
4132// that hangs up when credentials are initially sent, and hangs up again when
4133// they are retried.
bncd16676a2016-07-20 16:23:014134TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334135 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4136 HttpRequestInfo request;
4137 request.method = "GET";
4138 request.url = GURL("https://www.example.org/");
4139
4140 // Configure against proxy server "myproxy:70".
4141 session_deps_.proxy_service =
4142 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4143
bnc87dcefc2017-05-25 12:47:584144 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334145 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584146 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334147 mock_handler->set_allows_default_credentials(true);
4148 auth_handler_factory->AddMockHandler(mock_handler.release(),
4149 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484150 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334151
4152 // Add NetLog just so can verify load timing information gets a NetLog ID.
4153 NetLog net_log;
4154 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094155 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334156
4157 // Should try to establish tunnel.
4158 MockWrite data_writes1[] = {
4159 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174160 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334161 "Proxy-Connection: keep-alive\r\n\r\n"),
4162
4163 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174164 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334165 "Proxy-Connection: keep-alive\r\n"
4166 "Proxy-Authorization: auth_token\r\n\r\n"),
4167 };
4168
4169 // The proxy responds to the connect with a 407, and then hangs up after the
4170 // second request is sent.
4171 MockRead data_reads1[] = {
4172 // No credentials.
4173 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4174 MockRead("Content-Length: 0\r\n"),
4175 MockRead("Proxy-Connection: keep-alive\r\n"),
4176 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4177 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4178 };
4179
4180 // HttpNetworkTransaction sees a reused connection that was closed with
4181 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4182 // request.
4183 MockWrite data_writes2[] = {
4184 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174185 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334186 "Proxy-Connection: keep-alive\r\n\r\n"),
4187 };
4188
4189 // The proxy, having had more than enough of us, just hangs up.
4190 MockRead data_reads2[] = {
4191 // No credentials.
4192 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4193 };
4194
4195 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4196 data_writes1, arraysize(data_writes1));
4197 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4198 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4199 data_writes2, arraysize(data_writes2));
4200 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4201
bnc87dcefc2017-05-25 12:47:584202 auto trans =
4203 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334204
4205 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204206 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014207 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334208
4209 const HttpResponseInfo* response = trans->GetResponseInfo();
4210 ASSERT_TRUE(response);
4211 ASSERT_TRUE(response->headers);
4212 EXPECT_TRUE(response->headers->IsKeepAlive());
4213 EXPECT_EQ(407, response->headers->response_code());
4214 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4215 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4216 EXPECT_FALSE(response->auth_challenge);
4217
4218 LoadTimingInfo load_timing_info;
4219 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4220
4221 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014222 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334223
4224 trans.reset();
4225 session->CloseAllConnections();
4226}
4227
4228// Test a proxy auth scheme that allows default credentials and a proxy server
4229// that hangs up when credentials are initially sent, and sends a challenge
4230// again they are retried.
bncd16676a2016-07-20 16:23:014231TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334232 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4233 HttpRequestInfo request;
4234 request.method = "GET";
4235 request.url = GURL("https://www.example.org/");
4236
4237 // Configure against proxy server "myproxy:70".
4238 session_deps_.proxy_service =
4239 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4240
bnc87dcefc2017-05-25 12:47:584241 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334242 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584243 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334244 mock_handler->set_allows_default_credentials(true);
4245 auth_handler_factory->AddMockHandler(mock_handler.release(),
4246 HttpAuth::AUTH_PROXY);
4247 // Add another handler for the second challenge. It supports default
4248 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584249 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334250 mock_handler->set_allows_default_credentials(true);
4251 auth_handler_factory->AddMockHandler(mock_handler.release(),
4252 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484253 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334254
4255 // Add NetLog just so can verify load timing information gets a NetLog ID.
4256 NetLog net_log;
4257 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094258 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334259
4260 // Should try to establish tunnel.
4261 MockWrite data_writes1[] = {
4262 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174263 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334264 "Proxy-Connection: keep-alive\r\n\r\n"),
4265 };
4266
4267 // The proxy responds to the connect with a 407, using a non-persistent
4268 // connection.
4269 MockRead data_reads1[] = {
4270 // No credentials.
4271 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4272 MockRead("Proxy-Authenticate: Mock\r\n"),
4273 MockRead("Proxy-Connection: close\r\n\r\n"),
4274 };
4275
4276 // Since the first connection was closed, need to establish another once given
4277 // credentials.
4278 MockWrite data_writes2[] = {
4279 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174280 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334281 "Proxy-Connection: keep-alive\r\n"
4282 "Proxy-Authorization: auth_token\r\n\r\n"),
4283 };
4284
4285 MockRead data_reads2[] = {
4286 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4287 MockRead("Proxy-Authenticate: Mock\r\n"),
4288 MockRead("Proxy-Connection: close\r\n\r\n"),
4289 };
4290
4291 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4292 data_writes1, arraysize(data_writes1));
4293 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4294 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4295 data_writes2, arraysize(data_writes2));
4296 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4297 SSLSocketDataProvider ssl(ASYNC, OK);
4298 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4299
bnc87dcefc2017-05-25 12:47:584300 auto trans =
4301 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334302
4303 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204304 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014305 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334306
4307 const HttpResponseInfo* response = trans->GetResponseInfo();
4308 ASSERT_TRUE(response);
4309 ASSERT_TRUE(response->headers);
4310 EXPECT_EQ(407, response->headers->response_code());
4311 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4312 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4313 EXPECT_FALSE(response->auth_challenge);
4314
4315 LoadTimingInfo load_timing_info;
4316 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4317
4318 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014319 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334320 response = trans->GetResponseInfo();
4321 ASSERT_TRUE(response);
4322 ASSERT_TRUE(response->headers);
4323 EXPECT_EQ(407, response->headers->response_code());
4324 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4325 EXPECT_TRUE(response->auth_challenge);
4326
4327 trans.reset();
4328 session->CloseAllConnections();
4329}
4330
asankae2257db2016-10-11 22:03:164331// A more nuanced test than GenerateAuthToken test which asserts that
4332// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4333// unnecessarily invalidated, and that if the server co-operates, the
4334// authentication handshake can continue with the same scheme but with a
4335// different identity.
4336TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4337 HttpRequestInfo request;
4338 request.method = "GET";
4339 request.url = GURL("http://www.example.org/");
4340
bnc87dcefc2017-05-25 12:47:584341 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164342 auth_handler_factory->set_do_init_from_challenge(true);
4343
4344 // First handler. Uses default credentials, but barfs at generate auth token.
bnc87dcefc2017-05-25 12:47:584345 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164346 mock_handler->set_allows_default_credentials(true);
4347 mock_handler->set_allows_explicit_credentials(true);
4348 mock_handler->set_connection_based(true);
4349 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4350 auth_handler_factory->AddMockHandler(mock_handler.release(),
4351 HttpAuth::AUTH_SERVER);
4352
4353 // Add another handler for the second challenge. It supports default
4354 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584355 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164356 mock_handler->set_allows_default_credentials(true);
4357 mock_handler->set_allows_explicit_credentials(true);
4358 mock_handler->set_connection_based(true);
4359 auth_handler_factory->AddMockHandler(mock_handler.release(),
4360 HttpAuth::AUTH_SERVER);
4361 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4362
4363 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4364
4365 MockWrite data_writes1[] = {
4366 MockWrite("GET / HTTP/1.1\r\n"
4367 "Host: www.example.org\r\n"
4368 "Connection: keep-alive\r\n\r\n"),
4369 };
4370
4371 MockRead data_reads1[] = {
4372 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4373 "WWW-Authenticate: Mock\r\n"
4374 "Connection: keep-alive\r\n\r\n"),
4375 };
4376
4377 // Identical to data_writes1[]. The AuthHandler encounters a
4378 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4379 // transaction procceds without an authorization header.
4380 MockWrite data_writes2[] = {
4381 MockWrite("GET / HTTP/1.1\r\n"
4382 "Host: www.example.org\r\n"
4383 "Connection: keep-alive\r\n\r\n"),
4384 };
4385
4386 MockRead data_reads2[] = {
4387 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4388 "WWW-Authenticate: Mock\r\n"
4389 "Connection: keep-alive\r\n\r\n"),
4390 };
4391
4392 MockWrite data_writes3[] = {
4393 MockWrite("GET / HTTP/1.1\r\n"
4394 "Host: www.example.org\r\n"
4395 "Connection: keep-alive\r\n"
4396 "Authorization: auth_token\r\n\r\n"),
4397 };
4398
4399 MockRead data_reads3[] = {
4400 MockRead("HTTP/1.1 200 OK\r\n"
4401 "Content-Length: 5\r\n"
4402 "Content-Type: text/plain\r\n"
4403 "Connection: keep-alive\r\n\r\n"
4404 "Hello"),
4405 };
4406
4407 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4408 data_writes1, arraysize(data_writes1));
4409 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4410
4411 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4412 data_writes2, arraysize(data_writes2));
4413 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4414
4415 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4416 data_writes3, arraysize(data_writes3));
4417 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4418
bnc87dcefc2017-05-25 12:47:584419 auto trans =
4420 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164421
4422 TestCompletionCallback callback;
4423 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4424 EXPECT_THAT(callback.GetResult(rv), IsOk());
4425
4426 const HttpResponseInfo* response = trans->GetResponseInfo();
4427 ASSERT_TRUE(response);
4428 ASSERT_TRUE(response->headers);
4429 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4430
4431 // The following three tests assert that an authentication challenge was
4432 // received and that the stack is ready to respond to the challenge using
4433 // ambient credentials.
4434 EXPECT_EQ(401, response->headers->response_code());
4435 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4436 EXPECT_FALSE(response->auth_challenge);
4437
4438 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4439 EXPECT_THAT(callback.GetResult(rv), IsOk());
4440 response = trans->GetResponseInfo();
4441 ASSERT_TRUE(response);
4442 ASSERT_TRUE(response->headers);
4443
4444 // The following three tests assert that an authentication challenge was
4445 // received and that the stack needs explicit credentials before it is ready
4446 // to respond to the challenge.
4447 EXPECT_EQ(401, response->headers->response_code());
4448 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4449 EXPECT_TRUE(response->auth_challenge);
4450
4451 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4452 EXPECT_THAT(callback.GetResult(rv), IsOk());
4453 response = trans->GetResponseInfo();
4454 ASSERT_TRUE(response);
4455 ASSERT_TRUE(response->headers);
4456 EXPECT_EQ(200, response->headers->response_code());
4457
4458 trans.reset();
4459 session->CloseAllConnections();
4460}
4461
[email protected]029c83b62013-01-24 05:28:204462// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014463TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204464 HttpRequestInfo request1;
4465 request1.method = "GET";
bncce36dca22015-04-21 22:11:234466 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204467
4468 HttpRequestInfo request2;
4469 request2.method = "GET";
bncce36dca22015-04-21 22:11:234470 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204471
4472 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134473 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514474 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074475 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204477
4478 // Since we have proxy, should try to establish tunnel.
4479 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174480 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4481 "Host: www.example.org:443\r\n"
4482 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204483
rsleevidb16bb02015-11-12 23:47:174484 MockWrite("GET /1 HTTP/1.1\r\n"
4485 "Host: www.example.org\r\n"
4486 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204487
rsleevidb16bb02015-11-12 23:47:174488 MockWrite("GET /2 HTTP/1.1\r\n"
4489 "Host: www.example.org\r\n"
4490 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204491 };
4492
4493 // The proxy responds to the connect with a 407, using a persistent
4494 // connection.
4495 MockRead data_reads1[] = {
4496 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4497
4498 MockRead("HTTP/1.1 200 OK\r\n"),
4499 MockRead("Content-Length: 1\r\n\r\n"),
4500 MockRead(SYNCHRONOUS, "1"),
4501
4502 MockRead("HTTP/1.1 200 OK\r\n"),
4503 MockRead("Content-Length: 2\r\n\r\n"),
4504 MockRead(SYNCHRONOUS, "22"),
4505 };
4506
4507 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4508 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074509 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204510 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074511 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204512
4513 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584514 auto trans1 =
4515 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204516
4517 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014518 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204519
4520 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014521 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204522
4523 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524524 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474525 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524526 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204527 EXPECT_EQ(1, response1->headers->GetContentLength());
4528
4529 LoadTimingInfo load_timing_info1;
4530 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4531 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4532
4533 trans1.reset();
4534
4535 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584536 auto trans2 =
4537 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204538
4539 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204541
4542 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014543 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204544
4545 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524546 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474547 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524548 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204549 EXPECT_EQ(2, response2->headers->GetContentLength());
4550
4551 LoadTimingInfo load_timing_info2;
4552 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4553 TestLoadTimingReused(load_timing_info2);
4554
4555 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4556
4557 trans2.reset();
4558 session->CloseAllConnections();
4559}
4560
4561// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014562TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204563 HttpRequestInfo request1;
4564 request1.method = "GET";
bncce36dca22015-04-21 22:11:234565 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204566
4567 HttpRequestInfo request2;
4568 request2.method = "GET";
bncce36dca22015-04-21 22:11:234569 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204570
4571 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034572 session_deps_.proxy_service =
4573 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514574 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074575 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204577
4578 // Since we have proxy, should try to establish tunnel.
4579 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174580 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4581 "Host: www.example.org:443\r\n"
4582 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204583
rsleevidb16bb02015-11-12 23:47:174584 MockWrite("GET /1 HTTP/1.1\r\n"
4585 "Host: www.example.org\r\n"
4586 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204587
rsleevidb16bb02015-11-12 23:47:174588 MockWrite("GET /2 HTTP/1.1\r\n"
4589 "Host: www.example.org\r\n"
4590 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204591 };
4592
4593 // The proxy responds to the connect with a 407, using a persistent
4594 // connection.
4595 MockRead data_reads1[] = {
4596 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4597
4598 MockRead("HTTP/1.1 200 OK\r\n"),
4599 MockRead("Content-Length: 1\r\n\r\n"),
4600 MockRead(SYNCHRONOUS, "1"),
4601
4602 MockRead("HTTP/1.1 200 OK\r\n"),
4603 MockRead("Content-Length: 2\r\n\r\n"),
4604 MockRead(SYNCHRONOUS, "22"),
4605 };
4606
4607 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4608 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074609 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204610 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204612
4613 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584614 auto trans1 =
4615 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204616
4617 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014618 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204619
4620 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014621 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204622
4623 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524624 ASSERT_TRUE(response1);
4625 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204626 EXPECT_EQ(1, response1->headers->GetContentLength());
4627
4628 LoadTimingInfo load_timing_info1;
4629 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4630 TestLoadTimingNotReusedWithPac(load_timing_info1,
4631 CONNECT_TIMING_HAS_SSL_TIMES);
4632
4633 trans1.reset();
4634
4635 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584636 auto trans2 =
4637 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204638
4639 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204641
4642 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014643 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204644
4645 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524646 ASSERT_TRUE(response2);
4647 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204648 EXPECT_EQ(2, response2->headers->GetContentLength());
4649
4650 LoadTimingInfo load_timing_info2;
4651 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4652 TestLoadTimingReusedWithPac(load_timing_info2);
4653
4654 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4655
4656 trans2.reset();
4657 session->CloseAllConnections();
4658}
4659
[email protected]2df19bb2010-08-25 20:13:464660// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014661TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274662 HttpRequestInfo request;
4663 request.method = "GET";
bncce36dca22015-04-21 22:11:234664 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274665
[email protected]2df19bb2010-08-25 20:13:464666 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034667 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514668 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074669 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464671
[email protected]2df19bb2010-08-25 20:13:464672 // Since we have proxy, should use full url
4673 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234674 MockWrite(
4675 "GET http://www.example.org/ HTTP/1.1\r\n"
4676 "Host: www.example.org\r\n"
4677 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464678 };
4679
4680 MockRead data_reads1[] = {
4681 MockRead("HTTP/1.1 200 OK\r\n"),
4682 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4683 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064684 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464685 };
4686
4687 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4688 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074689 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064690 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074691 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464692
[email protected]49639fa2011-12-20 23:22:414693 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464694
bnc691fda62016-08-12 00:43:164695 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504696
bnc691fda62016-08-12 00:43:164697 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464699
4700 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014701 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464702
[email protected]58e32bb2013-01-21 18:23:254703 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164704 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254705 TestLoadTimingNotReused(load_timing_info,
4706 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4707
bnc691fda62016-08-12 00:43:164708 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524709 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464710
tbansal2ecbbc72016-10-06 17:15:474711 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464712 EXPECT_TRUE(response->headers->IsKeepAlive());
4713 EXPECT_EQ(200, response->headers->response_code());
4714 EXPECT_EQ(100, response->headers->GetContentLength());
4715 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4716
4717 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524718 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464719}
4720
[email protected]7642b5ae2010-09-01 20:55:174721// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014722TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274723 HttpRequestInfo request;
4724 request.method = "GET";
bncce36dca22015-04-21 22:11:234725 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274726
[email protected]7642b5ae2010-09-01 20:55:174727 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034728 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514729 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074730 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174732
bncce36dca22015-04-21 22:11:234733 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414734 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454735 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414736 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174737
bnc42331402016-07-25 13:36:154738 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414739 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174740 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414741 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174742 };
4743
rch8e6c6c42015-05-01 14:05:134744 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4745 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074746 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174747
[email protected]8ddf8322012-02-23 18:08:064748 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364749 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174751
[email protected]49639fa2011-12-20 23:22:414752 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174753
bnc691fda62016-08-12 00:43:164754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504755
bnc691fda62016-08-12 00:43:164756 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174758
4759 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014760 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174761
[email protected]58e32bb2013-01-21 18:23:254762 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164763 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254764 TestLoadTimingNotReused(load_timing_info,
4765 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4766
bnc691fda62016-08-12 00:43:164767 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524768 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474769 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524770 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024771 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174772
4773 std::string response_data;
bnc691fda62016-08-12 00:43:164774 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234775 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174776}
4777
[email protected]1c173852014-06-19 12:51:504778// Verifies that a session which races and wins against the owning transaction
4779// (completing prior to host resolution), doesn't fail the transaction.
4780// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014781TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504782 HttpRequestInfo request;
4783 request.method = "GET";
bncce36dca22015-04-21 22:11:234784 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504785
4786 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034787 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514788 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504789 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504791
bncce36dca22015-04-21 22:11:234792 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414793 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454794 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414795 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504796
bnc42331402016-07-25 13:36:154797 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414798 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504799 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414800 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504801 };
4802
rch8e6c6c42015-05-01 14:05:134803 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4804 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504805 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4806
4807 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364808 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4810
4811 TestCompletionCallback callback1;
4812
bnc691fda62016-08-12 00:43:164813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504814
4815 // Stall the hostname resolution begun by the transaction.
4816 session_deps_.host_resolver->set_synchronous_mode(false);
4817 session_deps_.host_resolver->set_ondemand_mode(true);
4818
bnc691fda62016-08-12 00:43:164819 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504821
4822 // Race a session to the proxy, which completes first.
4823 session_deps_.host_resolver->set_ondemand_mode(false);
4824 SpdySessionKey key(
4825 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4826 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:524827 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504828
4829 // Unstall the resolution begun by the transaction.
4830 session_deps_.host_resolver->set_ondemand_mode(true);
4831 session_deps_.host_resolver->ResolveAllPending();
4832
4833 EXPECT_FALSE(callback1.have_result());
4834 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014835 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504836
bnc691fda62016-08-12 00:43:164837 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524838 ASSERT_TRUE(response);
4839 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024840 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504841
4842 std::string response_data;
bnc691fda62016-08-12 00:43:164843 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504844 EXPECT_EQ(kUploadData, response_data);
4845}
4846
[email protected]dc7bd1c52010-11-12 00:01:134847// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014848TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274849 HttpRequestInfo request;
4850 request.method = "GET";
bncce36dca22015-04-21 22:11:234851 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274852
[email protected]79cb5c12011-09-12 13:12:044853 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034854 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514855 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074856 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094857 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134858
[email protected]dc7bd1c52010-11-12 00:01:134859 // The first request will be a bare GET, the second request will be a
4860 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454861 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414862 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494863 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384864 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134865 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464866 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134867 };
bncdf80d44fd2016-07-15 20:27:414868 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4869 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4870 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134871 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414872 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134873 };
4874
4875 // The first response is a 407 proxy authentication challenge, and the second
4876 // response will be a 200 response since the second request includes a valid
4877 // Authorization header.
4878 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464879 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134880 };
bnc42331402016-07-25 13:36:154881 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234882 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414883 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4884 SpdySerializedFrame body_authentication(
4885 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154886 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414887 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134888 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414889 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464890 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414891 CreateMockRead(resp_data, 4),
4892 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134893 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134894 };
4895
rch8e6c6c42015-05-01 14:05:134896 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4897 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074898 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134899
[email protected]8ddf8322012-02-23 18:08:064900 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364901 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074902 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134903
[email protected]49639fa2011-12-20 23:22:414904 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134905
bnc691fda62016-08-12 00:43:164906 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134907
bnc691fda62016-08-12 00:43:164908 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134910
4911 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014912 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134913
bnc691fda62016-08-12 00:43:164914 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134915
wezca1070932016-05-26 20:30:524916 ASSERT_TRUE(response);
4917 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134918 EXPECT_EQ(407, response->headers->response_code());
4919 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434920 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134921
[email protected]49639fa2011-12-20 23:22:414922 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134923
bnc691fda62016-08-12 00:43:164924 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134926
4927 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014928 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134929
bnc691fda62016-08-12 00:43:164930 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134931
wezca1070932016-05-26 20:30:524932 ASSERT_TRUE(response_restart);
4933 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134934 EXPECT_EQ(200, response_restart->headers->response_code());
4935 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524936 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134937}
4938
[email protected]d9da5fe2010-10-13 22:37:164939// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014940TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274941 HttpRequestInfo request;
4942 request.method = "GET";
bncce36dca22015-04-21 22:11:234943 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274944
[email protected]d9da5fe2010-10-13 22:37:164945 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034946 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514947 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074948 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094949 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164950
bnc691fda62016-08-12 00:43:164951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164952
bncce36dca22015-04-21 22:11:234953 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414954 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234955 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4956 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164957
bncce36dca22015-04-21 22:11:234958 const char get[] =
4959 "GET / HTTP/1.1\r\n"
4960 "Host: www.example.org\r\n"
4961 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414962 SpdySerializedFrame wrapped_get(
4963 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154964 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164965 const char resp[] = "HTTP/1.1 200 OK\r\n"
4966 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414967 SpdySerializedFrame wrapped_get_resp(
4968 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4969 SpdySerializedFrame wrapped_body(
4970 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4971 SpdySerializedFrame window_update(
4972 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044973
4974 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414975 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4976 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044977 };
4978
[email protected]d9da5fe2010-10-13 22:37:164979 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414980 CreateMockRead(conn_resp, 1, ASYNC),
4981 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4982 CreateMockRead(wrapped_body, 4, ASYNC),
4983 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134984 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164985 };
4986
rch8e6c6c42015-05-01 14:05:134987 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4988 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074989 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164990
[email protected]8ddf8322012-02-23 18:08:064991 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364992 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074993 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064994 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164996
[email protected]49639fa2011-12-20 23:22:414997 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164998
bnc691fda62016-08-12 00:43:164999 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165001
5002 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015003 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165004
[email protected]58e32bb2013-01-21 18:23:255005 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165006 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255007 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5008
bnc691fda62016-08-12 00:43:165009 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525010 ASSERT_TRUE(response);
5011 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165012 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5013
5014 std::string response_data;
bnc691fda62016-08-12 00:43:165015 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165016 EXPECT_EQ("1234567890", response_data);
5017}
5018
5019// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015020TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5021 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385022
[email protected]cb9bf6ca2011-01-28 13:15:275023 HttpRequestInfo request;
5024 request.method = "GET";
bncce36dca22015-04-21 22:11:235025 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275026
[email protected]d9da5fe2010-10-13 22:37:165027 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035028 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515029 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075030 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165032
bnc691fda62016-08-12 00:43:165033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165034
bncce36dca22015-04-21 22:11:235035 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415036 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235037 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5038 // fetch https://www.example.org/ via SPDY
5039 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415040 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495041 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415042 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155043 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415044 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155045 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415046 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025047 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415048 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5049 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025050 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415051 SpdySerializedFrame window_update_get_resp(
5052 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5053 SpdySerializedFrame window_update_body(
5054 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045055
5056 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415057 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5058 CreateMockWrite(window_update_get_resp, 6),
5059 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045060 };
5061
[email protected]d9da5fe2010-10-13 22:37:165062 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415063 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095064 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415065 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5066 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135067 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165068 };
5069
rch32320842015-05-16 15:57:095070 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5071 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075072 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165073
[email protected]8ddf8322012-02-23 18:08:065074 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365075 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075076 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065077 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365078 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165080
[email protected]49639fa2011-12-20 23:22:415081 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165082
bnc691fda62016-08-12 00:43:165083 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165085
rch32320842015-05-16 15:57:095086 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555087 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095088 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595089 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165090 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015091 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165092
[email protected]58e32bb2013-01-21 18:23:255093 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165094 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255095 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5096
bnc691fda62016-08-12 00:43:165097 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525098 ASSERT_TRUE(response);
5099 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025100 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165101
5102 std::string response_data;
bnc691fda62016-08-12 00:43:165103 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235104 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165105}
5106
5107// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015108TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275109 HttpRequestInfo request;
5110 request.method = "GET";
bncce36dca22015-04-21 22:11:235111 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275112
[email protected]d9da5fe2010-10-13 22:37:165113 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035114 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515115 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075116 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165118
bnc691fda62016-08-12 00:43:165119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165120
bncce36dca22015-04-21 22:11:235121 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415122 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235123 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415124 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085125 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165126
5127 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415128 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165129 };
5130
bnc42331402016-07-25 13:36:155131 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415132 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165133 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415134 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165135 };
5136
rch8e6c6c42015-05-01 14:05:135137 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5138 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075139 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165140
[email protected]8ddf8322012-02-23 18:08:065141 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365142 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075143 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065144 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365145 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165147
[email protected]49639fa2011-12-20 23:22:415148 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165149
bnc691fda62016-08-12 00:43:165150 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015151 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165152
5153 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015154 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165155
ttuttle960fcbf2016-04-19 13:26:325156 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165157}
5158
[email protected]f6c63db52013-02-02 00:35:225159// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5160// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015161TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225162 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5163 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035164 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515165 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075166 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095167 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505168 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225169
5170 HttpRequestInfo request1;
5171 request1.method = "GET";
bncce36dca22015-04-21 22:11:235172 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225173 request1.load_flags = 0;
5174
5175 HttpRequestInfo request2;
5176 request2.method = "GET";
bncce36dca22015-04-21 22:11:235177 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225178 request2.load_flags = 0;
5179
bncce36dca22015-04-21 22:11:235180 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415181 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235182 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155183 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225184
bncce36dca22015-04-21 22:11:235185 // Fetch https://www.example.org/ via HTTP.
5186 const char get1[] =
5187 "GET / HTTP/1.1\r\n"
5188 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225189 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415190 SpdySerializedFrame wrapped_get1(
5191 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225192 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5193 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415194 SpdySerializedFrame wrapped_get_resp1(
5195 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5196 SpdySerializedFrame wrapped_body1(
5197 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5198 SpdySerializedFrame window_update(
5199 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225200
bncce36dca22015-04-21 22:11:235201 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295202 SpdyHeaderBlock connect2_block;
5203 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405204 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155205 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5206 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395207
bnc42331402016-07-25 13:36:155208 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225209
bncce36dca22015-04-21 22:11:235210 // Fetch https://mail.example.org/ via HTTP.
5211 const char get2[] =
5212 "GET / HTTP/1.1\r\n"
5213 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225214 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415215 SpdySerializedFrame wrapped_get2(
5216 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225217 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5218 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415219 SpdySerializedFrame wrapped_get_resp2(
5220 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5221 SpdySerializedFrame wrapped_body2(
5222 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225223
5224 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415225 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5226 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225227 };
5228
5229 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415230 CreateMockRead(conn_resp1, 1, ASYNC),
5231 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5232 CreateMockRead(wrapped_body1, 4, ASYNC),
5233 CreateMockRead(conn_resp2, 6, ASYNC),
5234 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5235 CreateMockRead(wrapped_body2, 9, ASYNC),
5236 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225237 };
5238
mmenke11eb5152015-06-09 14:50:505239 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5240 arraysize(spdy_writes));
5241 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225242
5243 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365244 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225246 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505247 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225248 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225250
5251 TestCompletionCallback callback;
5252
bnc691fda62016-08-12 00:43:165253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205254 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015255 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225256
5257 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165258 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225259 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5260
bnc691fda62016-08-12 00:43:165261 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525262 ASSERT_TRUE(response);
5263 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225264 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5265
5266 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295267 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165268 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505269 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225270
bnc691fda62016-08-12 00:43:165271 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205272 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015273 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225274
5275 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165276 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225277 // Even though the SPDY connection is reused, a new tunnelled connection has
5278 // to be created, so the socket's load timing looks like a fresh connection.
5279 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5280
5281 // The requests should have different IDs, since they each are using their own
5282 // separate stream.
5283 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5284
bnc691fda62016-08-12 00:43:165285 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505286 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225287}
5288
5289// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5290// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015291TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225292 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5293 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035294 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515295 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075296 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095297 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505298 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225299
5300 HttpRequestInfo request1;
5301 request1.method = "GET";
bncce36dca22015-04-21 22:11:235302 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225303 request1.load_flags = 0;
5304
5305 HttpRequestInfo request2;
5306 request2.method = "GET";
bncce36dca22015-04-21 22:11:235307 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225308 request2.load_flags = 0;
5309
bncce36dca22015-04-21 22:11:235310 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415311 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235312 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155313 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225314
bncce36dca22015-04-21 22:11:235315 // Fetch https://www.example.org/ via HTTP.
5316 const char get1[] =
5317 "GET / HTTP/1.1\r\n"
5318 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225319 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415320 SpdySerializedFrame wrapped_get1(
5321 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225322 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5323 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415324 SpdySerializedFrame wrapped_get_resp1(
5325 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5326 SpdySerializedFrame wrapped_body1(
5327 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5328 SpdySerializedFrame window_update(
5329 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225330
bncce36dca22015-04-21 22:11:235331 // Fetch https://www.example.org/2 via HTTP.
5332 const char get2[] =
5333 "GET /2 HTTP/1.1\r\n"
5334 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225335 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415336 SpdySerializedFrame wrapped_get2(
5337 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225338 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5339 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415340 SpdySerializedFrame wrapped_get_resp2(
5341 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5342 SpdySerializedFrame wrapped_body2(
5343 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225344
5345 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415346 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5347 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225348 };
5349
5350 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415351 CreateMockRead(conn_resp1, 1, ASYNC),
5352 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465353 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415354 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465355 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415356 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225357 };
5358
mmenke11eb5152015-06-09 14:50:505359 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5360 arraysize(spdy_writes));
5361 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225362
5363 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365364 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225366 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225368
5369 TestCompletionCallback callback;
5370
bnc87dcefc2017-05-25 12:47:585371 auto trans =
5372 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205373 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225375
5376 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015377 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225378
5379 LoadTimingInfo load_timing_info;
5380 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5381 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5382
5383 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525384 ASSERT_TRUE(response);
5385 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225386 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5387
5388 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295389 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505390 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225391 trans.reset();
5392
bnc87dcefc2017-05-25 12:47:585393 auto trans2 =
5394 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205395 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225397
[email protected]f6c63db52013-02-02 00:35:225398 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015399 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225400
5401 LoadTimingInfo load_timing_info2;
5402 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5403 TestLoadTimingReused(load_timing_info2);
5404
5405 // The requests should have the same ID.
5406 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5407
[email protected]90499482013-06-01 00:39:505408 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225409}
5410
5411// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5412// Proxy to different servers.
bncd16676a2016-07-20 16:23:015413TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225414 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035415 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515416 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075417 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095418 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505419 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225420
5421 HttpRequestInfo request1;
5422 request1.method = "GET";
bncce36dca22015-04-21 22:11:235423 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225424 request1.load_flags = 0;
5425
5426 HttpRequestInfo request2;
5427 request2.method = "GET";
bncce36dca22015-04-21 22:11:235428 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225429 request2.load_flags = 0;
5430
bncce36dca22015-04-21 22:11:235431 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265432 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235433 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415434 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155435 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5436 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415437 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385438 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225439
bncce36dca22015-04-21 22:11:235440 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265441 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235442 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415443 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155444 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5445 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415446 SpdySerializedFrame body2(
5447 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225448
5449 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415450 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225451 };
5452
5453 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415454 CreateMockRead(get_resp1, 1, ASYNC),
5455 CreateMockRead(body1, 2, ASYNC),
5456 CreateMockRead(get_resp2, 4, ASYNC),
5457 CreateMockRead(body2, 5, ASYNC),
5458 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225459 };
5460
mmenke11eb5152015-06-09 14:50:505461 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5462 arraysize(spdy_writes));
5463 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225464
5465 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365466 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225468
5469 TestCompletionCallback callback;
5470
bnc87dcefc2017-05-25 12:47:585471 auto trans =
5472 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205473 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015474 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225475
5476 LoadTimingInfo load_timing_info;
5477 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5478 TestLoadTimingNotReused(load_timing_info,
5479 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5480
5481 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525482 ASSERT_TRUE(response);
5483 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025484 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225485
5486 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295487 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505488 rv = trans->Read(buf.get(), 256, callback.callback());
5489 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225490 // Delete the first request, so the second one can reuse the socket.
5491 trans.reset();
5492
bnc691fda62016-08-12 00:43:165493 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205494 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015495 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225496
5497 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165498 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225499 TestLoadTimingReused(load_timing_info2);
5500
5501 // The requests should have the same ID.
5502 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5503
bnc691fda62016-08-12 00:43:165504 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505505 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225506}
5507
[email protected]2df19bb2010-08-25 20:13:465508// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015509TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465510 HttpRequestInfo request;
5511 request.method = "GET";
bncce36dca22015-04-21 22:11:235512 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465513 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295514 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465515
[email protected]79cb5c12011-09-12 13:12:045516 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035517 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515518 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075519 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275521
[email protected]2df19bb2010-08-25 20:13:465522 // Since we have proxy, should use full url
5523 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165524 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5525 "Host: www.example.org\r\n"
5526 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465527
bnc691fda62016-08-12 00:43:165528 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235529 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165530 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5531 "Host: www.example.org\r\n"
5532 "Proxy-Connection: keep-alive\r\n"
5533 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465534 };
5535
5536 // The proxy responds to the GET with a 407, using a persistent
5537 // connection.
5538 MockRead data_reads1[] = {
5539 // No credentials.
5540 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5541 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5542 MockRead("Proxy-Connection: keep-alive\r\n"),
5543 MockRead("Content-Length: 0\r\n\r\n"),
5544
5545 MockRead("HTTP/1.1 200 OK\r\n"),
5546 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5547 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065548 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465549 };
5550
5551 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5552 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075553 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065554 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075555 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465556
[email protected]49639fa2011-12-20 23:22:415557 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465558
bnc691fda62016-08-12 00:43:165559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505560
bnc691fda62016-08-12 00:43:165561 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015562 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465563
5564 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015565 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465566
[email protected]58e32bb2013-01-21 18:23:255567 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165568 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255569 TestLoadTimingNotReused(load_timing_info,
5570 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5571
bnc691fda62016-08-12 00:43:165572 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525573 ASSERT_TRUE(response);
5574 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465575 EXPECT_EQ(407, response->headers->response_code());
5576 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435577 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465578
[email protected]49639fa2011-12-20 23:22:415579 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465580
bnc691fda62016-08-12 00:43:165581 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465583
5584 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015585 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465586
[email protected]58e32bb2013-01-21 18:23:255587 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165588 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255589 // Retrying with HTTP AUTH is considered to be reusing a socket.
5590 TestLoadTimingReused(load_timing_info);
5591
bnc691fda62016-08-12 00:43:165592 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525593 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465594
5595 EXPECT_TRUE(response->headers->IsKeepAlive());
5596 EXPECT_EQ(200, response->headers->response_code());
5597 EXPECT_EQ(100, response->headers->GetContentLength());
5598 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5599
5600 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525601 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465602}
5603
[email protected]23e482282013-06-14 16:08:025604void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085605 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425606 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085607 request.method = "GET";
bncce36dca22015-04-21 22:11:235608 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085609
[email protected]cb9bf6ca2011-01-28 13:15:275610 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035611 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275613
[email protected]c744cf22009-02-27 07:28:085614 // Since we have proxy, should try to establish tunnel.
5615 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175616 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5617 "Host: www.example.org:443\r\n"
5618 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085619 };
5620
5621 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235622 status, MockRead("Content-Length: 10\r\n\r\n"),
5623 // No response body because the test stops reading here.
5624 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085625 };
5626
[email protected]31a2bfe2010-02-09 08:03:395627 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5628 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075629 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085630
[email protected]49639fa2011-12-20 23:22:415631 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085632
bnc691fda62016-08-12 00:43:165633 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505634
tfarina42834112016-09-22 13:38:205635 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085637
5638 rv = callback.WaitForResult();
5639 EXPECT_EQ(expected_status, rv);
5640}
5641
[email protected]23e482282013-06-14 16:08:025642void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235643 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085644 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425645 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085646}
5647
bncd16676a2016-07-20 16:23:015648TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085649 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5650}
5651
bncd16676a2016-07-20 16:23:015652TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085653 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5654}
5655
bncd16676a2016-07-20 16:23:015656TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085657 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5658}
5659
bncd16676a2016-07-20 16:23:015660TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085661 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5662}
5663
bncd16676a2016-07-20 16:23:015664TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085665 ConnectStatusHelper(
5666 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5667}
5668
bncd16676a2016-07-20 16:23:015669TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085670 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5671}
5672
bncd16676a2016-07-20 16:23:015673TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085674 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5675}
5676
bncd16676a2016-07-20 16:23:015677TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085678 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5679}
5680
bncd16676a2016-07-20 16:23:015681TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085682 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5683}
5684
bncd16676a2016-07-20 16:23:015685TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085686 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5687}
5688
bncd16676a2016-07-20 16:23:015689TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085690 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5691}
5692
bncd16676a2016-07-20 16:23:015693TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085694 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5695}
5696
bncd16676a2016-07-20 16:23:015697TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085698 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5699}
5700
bncd16676a2016-07-20 16:23:015701TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085702 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5703}
5704
bncd16676a2016-07-20 16:23:015705TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085706 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5707}
5708
bncd16676a2016-07-20 16:23:015709TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085710 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5711}
5712
bncd16676a2016-07-20 16:23:015713TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375714 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5715}
5716
bncd16676a2016-07-20 16:23:015717TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085718 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5719}
5720
bncd16676a2016-07-20 16:23:015721TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085722 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5723}
5724
bncd16676a2016-07-20 16:23:015725TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085726 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5727}
5728
bncd16676a2016-07-20 16:23:015729TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085730 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5731}
5732
bncd16676a2016-07-20 16:23:015733TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085734 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5735}
5736
bncd16676a2016-07-20 16:23:015737TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085738 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5739}
5740
bncd16676a2016-07-20 16:23:015741TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085742 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5743}
5744
bncd16676a2016-07-20 16:23:015745TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085746 ConnectStatusHelperWithExpectedStatus(
5747 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545748 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085749}
5750
bncd16676a2016-07-20 16:23:015751TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085752 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5753}
5754
bncd16676a2016-07-20 16:23:015755TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085756 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5757}
5758
bncd16676a2016-07-20 16:23:015759TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085760 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5761}
5762
bncd16676a2016-07-20 16:23:015763TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085764 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5765}
5766
bncd16676a2016-07-20 16:23:015767TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085768 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5769}
5770
bncd16676a2016-07-20 16:23:015771TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085772 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5773}
5774
bncd16676a2016-07-20 16:23:015775TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085776 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5777}
5778
bncd16676a2016-07-20 16:23:015779TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085780 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5781}
5782
bncd16676a2016-07-20 16:23:015783TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085784 ConnectStatusHelper(
5785 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5786}
5787
bncd16676a2016-07-20 16:23:015788TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085789 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5790}
5791
bncd16676a2016-07-20 16:23:015792TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085793 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5794}
5795
bncd16676a2016-07-20 16:23:015796TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085797 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5798}
5799
bncd16676a2016-07-20 16:23:015800TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085801 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5802}
5803
bncd16676a2016-07-20 16:23:015804TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085805 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5806}
5807
bncd16676a2016-07-20 16:23:015808TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085809 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5810}
5811
bncd16676a2016-07-20 16:23:015812TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085813 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5814}
5815
[email protected]038e9a32008-10-08 22:40:165816// Test the flow when both the proxy server AND origin server require
5817// authentication. Again, this uses basic auth for both since that is
5818// the simplest to mock.
bncd16676a2016-07-20 16:23:015819TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275820 HttpRequestInfo request;
5821 request.method = "GET";
bncce36dca22015-04-21 22:11:235822 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275823
[email protected]038e9a32008-10-08 22:40:165824 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035825 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075827
bnc691fda62016-08-12 00:43:165828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165829
[email protected]f9ee6b52008-11-08 06:46:235830 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235831 MockWrite(
5832 "GET http://www.example.org/ HTTP/1.1\r\n"
5833 "Host: www.example.org\r\n"
5834 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235835 };
5836
[email protected]038e9a32008-10-08 22:40:165837 MockRead data_reads1[] = {
5838 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5839 // Give a couple authenticate options (only the middle one is actually
5840 // supported).
[email protected]22927ad2009-09-21 19:56:195841 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165842 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5843 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5844 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5845 // Large content-length -- won't matter, as connection will be reset.
5846 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065847 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165848 };
5849
bnc691fda62016-08-12 00:43:165850 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165851 // request we should be issuing -- the final header line contains the
5852 // proxy's credentials.
5853 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235854 MockWrite(
5855 "GET http://www.example.org/ HTTP/1.1\r\n"
5856 "Host: www.example.org\r\n"
5857 "Proxy-Connection: keep-alive\r\n"
5858 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165859 };
5860
5861 // Now the proxy server lets the request pass through to origin server.
5862 // The origin server responds with a 401.
5863 MockRead data_reads2[] = {
5864 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5865 // Note: We are using the same realm-name as the proxy server. This is
5866 // completely valid, as realms are unique across hosts.
5867 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5868 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5869 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065870 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165871 };
5872
bnc691fda62016-08-12 00:43:165873 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165874 // the credentials for both the proxy and origin server.
5875 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235876 MockWrite(
5877 "GET http://www.example.org/ HTTP/1.1\r\n"
5878 "Host: www.example.org\r\n"
5879 "Proxy-Connection: keep-alive\r\n"
5880 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5881 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165882 };
5883
5884 // Lastly we get the desired content.
5885 MockRead data_reads3[] = {
5886 MockRead("HTTP/1.0 200 OK\r\n"),
5887 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5888 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065889 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165890 };
5891
[email protected]31a2bfe2010-02-09 08:03:395892 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5893 data_writes1, arraysize(data_writes1));
5894 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5895 data_writes2, arraysize(data_writes2));
5896 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5897 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075898 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5899 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5900 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165901
[email protected]49639fa2011-12-20 23:22:415902 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165903
tfarina42834112016-09-22 13:38:205904 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165906
5907 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015908 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165909
bnc691fda62016-08-12 00:43:165910 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525911 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045912 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165913
[email protected]49639fa2011-12-20 23:22:415914 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165915
bnc691fda62016-08-12 00:43:165916 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165918
5919 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015920 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165921
bnc691fda62016-08-12 00:43:165922 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525923 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045924 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165925
[email protected]49639fa2011-12-20 23:22:415926 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165927
bnc691fda62016-08-12 00:43:165928 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5929 callback3.callback());
robpercival214763f2016-07-01 23:27:015930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165931
5932 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015933 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165934
bnc691fda62016-08-12 00:43:165935 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525936 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165937 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165938}
[email protected]4ddaf2502008-10-23 18:26:195939
[email protected]ea9dc9a2009-09-05 00:43:325940// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5941// can't hook into its internals to cause it to generate predictable NTLM
5942// authorization headers.
5943#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295944// The NTLM authentication unit tests were generated by capturing the HTTP
5945// requests and responses using Fiddler 2 and inspecting the generated random
5946// bytes in the debugger.
5947
5948// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015949TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425950 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245951 request.method = "GET";
5952 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545953
5954 // Ensure load is not disrupted by flags which suppress behaviour specific
5955 // to other auth schemes.
5956 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245957
[email protected]cb9bf6ca2011-01-28 13:15:275958 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5959 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095960 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275961
[email protected]3f918782009-02-28 01:29:245962 MockWrite data_writes1[] = {
5963 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5964 "Host: 172.22.68.17\r\n"
5965 "Connection: keep-alive\r\n\r\n"),
5966 };
5967
5968 MockRead data_reads1[] = {
5969 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045970 // Negotiate and NTLM are often requested together. However, we only want
5971 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5972 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245973 MockRead("WWW-Authenticate: NTLM\r\n"),
5974 MockRead("Connection: close\r\n"),
5975 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365976 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245977 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065978 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245979 };
5980
5981 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165982 // After restarting with a null identity, this is the
5983 // request we should be issuing -- the final header line contains a Type
5984 // 1 message.
5985 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5986 "Host: 172.22.68.17\r\n"
5987 "Connection: keep-alive\r\n"
5988 "Authorization: NTLM "
5989 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245990
bnc691fda62016-08-12 00:43:165991 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5992 // (the credentials for the origin server). The second request continues
5993 // on the same connection.
5994 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5995 "Host: 172.22.68.17\r\n"
5996 "Connection: keep-alive\r\n"
5997 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5998 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5999 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
6000 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
6001 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246002 };
6003
6004 MockRead data_reads2[] = {
6005 // The origin server responds with a Type 2 message.
6006 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6007 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:296008 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:246009 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6010 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6011 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6012 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6013 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6014 "BtAAAAAAA=\r\n"),
6015 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366016 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246017 MockRead("You are not authorized to view this page\r\n"),
6018
6019 // Lastly we get the desired content.
6020 MockRead("HTTP/1.1 200 OK\r\n"),
6021 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6022 MockRead("Content-Length: 13\r\n\r\n"),
6023 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066024 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:246025 };
6026
[email protected]31a2bfe2010-02-09 08:03:396027 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6028 data_writes1, arraysize(data_writes1));
6029 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6030 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076031 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6032 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246033
[email protected]49639fa2011-12-20 23:22:416034 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246035
bnc691fda62016-08-12 00:43:166036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506037
tfarina42834112016-09-22 13:38:206038 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246040
6041 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016042 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246043
bnc691fda62016-08-12 00:43:166044 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226045
bnc691fda62016-08-12 00:43:166046 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526047 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046048 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246049
[email protected]49639fa2011-12-20 23:22:416050 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256051
bnc691fda62016-08-12 00:43:166052 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6053 callback2.callback());
robpercival214763f2016-07-01 23:27:016054 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256055
6056 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016057 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256058
bnc691fda62016-08-12 00:43:166059 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256060
bnc691fda62016-08-12 00:43:166061 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526062 ASSERT_TRUE(response);
6063 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256064
[email protected]49639fa2011-12-20 23:22:416065 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246066
bnc691fda62016-08-12 00:43:166067 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016068 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246069
[email protected]0757e7702009-03-27 04:00:226070 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016071 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246072
bnc691fda62016-08-12 00:43:166073 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526074 ASSERT_TRUE(response);
6075 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:246076 EXPECT_EQ(13, response->headers->GetContentLength());
6077}
6078
[email protected]385a4672009-03-11 22:21:296079// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:016080TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:426081 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296082 request.method = "GET";
6083 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296084
[email protected]cb9bf6ca2011-01-28 13:15:276085 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
6086 MockGetHostName);
danakj1fd259a02016-04-16 03:17:096087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276088
[email protected]385a4672009-03-11 22:21:296089 MockWrite data_writes1[] = {
6090 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6091 "Host: 172.22.68.17\r\n"
6092 "Connection: keep-alive\r\n\r\n"),
6093 };
6094
6095 MockRead data_reads1[] = {
6096 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046097 // Negotiate and NTLM are often requested together. However, we only want
6098 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6099 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296100 MockRead("WWW-Authenticate: NTLM\r\n"),
6101 MockRead("Connection: close\r\n"),
6102 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366103 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296104 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066105 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296106 };
6107
6108 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166109 // After restarting with a null identity, this is the
6110 // request we should be issuing -- the final header line contains a Type
6111 // 1 message.
6112 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6113 "Host: 172.22.68.17\r\n"
6114 "Connection: keep-alive\r\n"
6115 "Authorization: NTLM "
6116 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296117
bnc691fda62016-08-12 00:43:166118 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6119 // (the credentials for the origin server). The second request continues
6120 // on the same connection.
6121 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6122 "Host: 172.22.68.17\r\n"
6123 "Connection: keep-alive\r\n"
6124 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6125 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6126 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6127 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6128 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296129 };
6130
6131 MockRead data_reads2[] = {
6132 // The origin server responds with a Type 2 message.
6133 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6134 MockRead("WWW-Authenticate: NTLM "
6135 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6136 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6137 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6138 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6139 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6140 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6141 "BtAAAAAAA=\r\n"),
6142 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366143 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296144 MockRead("You are not authorized to view this page\r\n"),
6145
6146 // Wrong password.
6147 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296148 MockRead("WWW-Authenticate: NTLM\r\n"),
6149 MockRead("Connection: close\r\n"),
6150 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366151 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296152 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066153 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296154 };
6155
6156 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166157 // After restarting with a null identity, this is the
6158 // request we should be issuing -- the final header line contains a Type
6159 // 1 message.
6160 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6161 "Host: 172.22.68.17\r\n"
6162 "Connection: keep-alive\r\n"
6163 "Authorization: NTLM "
6164 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296165
bnc691fda62016-08-12 00:43:166166 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6167 // (the credentials for the origin server). The second request continues
6168 // on the same connection.
6169 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6170 "Host: 172.22.68.17\r\n"
6171 "Connection: keep-alive\r\n"
6172 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6173 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6174 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6175 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6176 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296177 };
6178
6179 MockRead data_reads3[] = {
6180 // The origin server responds with a Type 2 message.
6181 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6182 MockRead("WWW-Authenticate: NTLM "
6183 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6184 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6185 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6186 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6187 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6188 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6189 "BtAAAAAAA=\r\n"),
6190 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366191 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296192 MockRead("You are not authorized to view this page\r\n"),
6193
6194 // Lastly we get the desired content.
6195 MockRead("HTTP/1.1 200 OK\r\n"),
6196 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6197 MockRead("Content-Length: 13\r\n\r\n"),
6198 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066199 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296200 };
6201
[email protected]31a2bfe2010-02-09 08:03:396202 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6203 data_writes1, arraysize(data_writes1));
6204 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6205 data_writes2, arraysize(data_writes2));
6206 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6207 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076208 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6209 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6210 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296211
[email protected]49639fa2011-12-20 23:22:416212 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296213
bnc691fda62016-08-12 00:43:166214 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506215
tfarina42834112016-09-22 13:38:206216 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296218
6219 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016220 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296221
bnc691fda62016-08-12 00:43:166222 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296223
bnc691fda62016-08-12 00:43:166224 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526225 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046226 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296227
[email protected]49639fa2011-12-20 23:22:416228 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296229
[email protected]0757e7702009-03-27 04:00:226230 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166231 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6232 callback2.callback());
robpercival214763f2016-07-01 23:27:016233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296234
[email protected]10af5fe72011-01-31 16:17:256235 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016236 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296237
bnc691fda62016-08-12 00:43:166238 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416239 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166240 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256242 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016243 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166244 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226245
bnc691fda62016-08-12 00:43:166246 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526247 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046248 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226249
[email protected]49639fa2011-12-20 23:22:416250 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226251
6252 // Now enter the right password.
bnc691fda62016-08-12 00:43:166253 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6254 callback4.callback());
robpercival214763f2016-07-01 23:27:016255 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256256
6257 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016258 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256259
bnc691fda62016-08-12 00:43:166260 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256261
[email protected]49639fa2011-12-20 23:22:416262 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256263
6264 // One more roundtrip
bnc691fda62016-08-12 00:43:166265 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226267
6268 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016269 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226270
bnc691fda62016-08-12 00:43:166271 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526272 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296273 EXPECT_EQ(13, response->headers->GetContentLength());
6274}
[email protected]ea9dc9a2009-09-05 00:43:326275#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296276
[email protected]4ddaf2502008-10-23 18:26:196277// Test reading a server response which has only headers, and no body.
6278// After some maximum number of bytes is consumed, the transaction should
6279// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016280TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426281 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196282 request.method = "GET";
bncce36dca22015-04-21 22:11:236283 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196284
danakj1fd259a02016-04-16 03:17:096285 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276287
[email protected]b75b7b2f2009-10-06 00:54:536288 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436289 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536290 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196291
6292 MockRead data_reads[] = {
6293 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066294 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196295 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066296 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196297 };
[email protected]31a2bfe2010-02-09 08:03:396298 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076299 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196300
[email protected]49639fa2011-12-20 23:22:416301 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196302
tfarina42834112016-09-22 13:38:206303 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196305
6306 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016307 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196308}
[email protected]f4e426b2008-11-05 00:24:496309
6310// Make sure that we don't try to reuse a TCPClientSocket when failing to
6311// establish tunnel.
6312// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016313TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276314 HttpRequestInfo request;
6315 request.method = "GET";
bncce36dca22015-04-21 22:11:236316 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276317
[email protected]f4e426b2008-11-05 00:24:496318 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036319 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016320
danakj1fd259a02016-04-16 03:17:096321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496322
bnc87dcefc2017-05-25 12:47:586323 auto trans =
6324 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496325
[email protected]f4e426b2008-11-05 00:24:496326 // Since we have proxy, should try to establish tunnel.
6327 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176328 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6329 "Host: www.example.org:443\r\n"
6330 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496331 };
6332
[email protected]77848d12008-11-14 00:00:226333 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496334 // connection. Usually a proxy would return 501 (not implemented),
6335 // or 200 (tunnel established).
6336 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236337 MockRead("HTTP/1.1 404 Not Found\r\n"),
6338 MockRead("Content-Length: 10\r\n\r\n"),
6339 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496340 };
6341
[email protected]31a2bfe2010-02-09 08:03:396342 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6343 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076344 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496345
[email protected]49639fa2011-12-20 23:22:416346 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496347
tfarina42834112016-09-22 13:38:206348 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496350
6351 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016352 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496353
[email protected]b4404c02009-04-10 16:38:526354 // Empty the current queue. This is necessary because idle sockets are
6355 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556356 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526357
[email protected]f4e426b2008-11-05 00:24:496358 // We now check to make sure the TCPClientSocket was not added back to
6359 // the pool.
[email protected]90499482013-06-01 00:39:506360 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496361 trans.reset();
fdoray92e35a72016-06-10 15:54:556362 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496363 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506364 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496365}
[email protected]372d34a2008-11-05 21:30:516366
[email protected]1b157c02009-04-21 01:55:406367// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016368TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426369 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406370 request.method = "GET";
bncce36dca22015-04-21 22:11:236371 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406372
danakj1fd259a02016-04-16 03:17:096373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276374
bnc691fda62016-08-12 00:43:166375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276376
[email protected]1b157c02009-04-21 01:55:406377 MockRead data_reads[] = {
6378 // A part of the response body is received with the response headers.
6379 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6380 // The rest of the response body is received in two parts.
6381 MockRead("lo"),
6382 MockRead(" world"),
6383 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066384 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406385 };
6386
[email protected]31a2bfe2010-02-09 08:03:396387 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076388 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406389
[email protected]49639fa2011-12-20 23:22:416390 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406391
tfarina42834112016-09-22 13:38:206392 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406394
6395 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016396 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406397
bnc691fda62016-08-12 00:43:166398 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526399 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406400
wezca1070932016-05-26 20:30:526401 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406402 std::string status_line = response->headers->GetStatusLine();
6403 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6404
[email protected]90499482013-06-01 00:39:506405 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406406
6407 std::string response_data;
bnc691fda62016-08-12 00:43:166408 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016409 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406410 EXPECT_EQ("hello world", response_data);
6411
6412 // Empty the current queue. This is necessary because idle sockets are
6413 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556414 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406415
6416 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506417 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406418}
6419
[email protected]76a505b2010-08-25 06:23:006420// Make sure that we recycle a SSL socket after reading all of the response
6421// body.
bncd16676a2016-07-20 16:23:016422TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006423 HttpRequestInfo request;
6424 request.method = "GET";
bncce36dca22015-04-21 22:11:236425 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006426
6427 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236428 MockWrite(
6429 "GET / HTTP/1.1\r\n"
6430 "Host: www.example.org\r\n"
6431 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006432 };
6433
6434 MockRead data_reads[] = {
6435 MockRead("HTTP/1.1 200 OK\r\n"),
6436 MockRead("Content-Length: 11\r\n\r\n"),
6437 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066438 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006439 };
6440
[email protected]8ddf8322012-02-23 18:08:066441 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076442 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006443
6444 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6445 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076446 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006447
[email protected]49639fa2011-12-20 23:22:416448 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006449
danakj1fd259a02016-04-16 03:17:096450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006452
tfarina42834112016-09-22 13:38:206453 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006454
robpercival214763f2016-07-01 23:27:016455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6456 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006457
bnc691fda62016-08-12 00:43:166458 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526459 ASSERT_TRUE(response);
6460 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006461 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6462
[email protected]90499482013-06-01 00:39:506463 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006464
6465 std::string response_data;
bnc691fda62016-08-12 00:43:166466 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016467 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006468 EXPECT_EQ("hello world", response_data);
6469
6470 // Empty the current queue. This is necessary because idle sockets are
6471 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556472 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006473
6474 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506475 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006476}
6477
6478// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6479// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016480TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006481 HttpRequestInfo request;
6482 request.method = "GET";
bncce36dca22015-04-21 22:11:236483 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006484
6485 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236486 MockWrite(
6487 "GET / HTTP/1.1\r\n"
6488 "Host: www.example.org\r\n"
6489 "Connection: keep-alive\r\n\r\n"),
6490 MockWrite(
6491 "GET / HTTP/1.1\r\n"
6492 "Host: www.example.org\r\n"
6493 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006494 };
6495
6496 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426497 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6498 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006499
[email protected]8ddf8322012-02-23 18:08:066500 SSLSocketDataProvider ssl(ASYNC, OK);
6501 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006504
6505 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6506 data_writes, arraysize(data_writes));
6507 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6508 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076509 session_deps_.socket_factory->AddSocketDataProvider(&data);
6510 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006511
[email protected]49639fa2011-12-20 23:22:416512 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006513
danakj1fd259a02016-04-16 03:17:096514 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586515 auto trans =
6516 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006517
tfarina42834112016-09-22 13:38:206518 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006519
robpercival214763f2016-07-01 23:27:016520 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6521 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006522
6523 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526524 ASSERT_TRUE(response);
6525 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006526 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6527
[email protected]90499482013-06-01 00:39:506528 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006529
6530 std::string response_data;
6531 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016532 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006533 EXPECT_EQ("hello world", response_data);
6534
6535 // Empty the current queue. This is necessary because idle sockets are
6536 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556537 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006538
6539 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506540 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006541
6542 // Now start the second transaction, which should reuse the previous socket.
6543
bnc87dcefc2017-05-25 12:47:586544 trans =
6545 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006546
tfarina42834112016-09-22 13:38:206547 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006548
robpercival214763f2016-07-01 23:27:016549 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6550 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006551
6552 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526553 ASSERT_TRUE(response);
6554 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006555 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6556
[email protected]90499482013-06-01 00:39:506557 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006558
6559 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016560 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006561 EXPECT_EQ("hello world", response_data);
6562
6563 // Empty the current queue. This is necessary because idle sockets are
6564 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556565 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006566
6567 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506568 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006569}
6570
maksim.sisov0adf8592016-07-15 06:25:566571// Grab a socket, use it, and put it back into the pool. Then, make
6572// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016573TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566574 HttpRequestInfo request;
6575 request.method = "GET";
6576 request.url = GURL("http://www.example.org/");
6577 request.load_flags = 0;
6578
6579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6580
bnc691fda62016-08-12 00:43:166581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566582
6583 MockRead data_reads[] = {
6584 // A part of the response body is received with the response headers.
6585 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6586 // The rest of the response body is received in two parts.
6587 MockRead("lo"), MockRead(" world"),
6588 MockRead("junk"), // Should not be read!!
6589 MockRead(SYNCHRONOUS, OK),
6590 };
6591
6592 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6593 session_deps_.socket_factory->AddSocketDataProvider(&data);
6594
6595 TestCompletionCallback callback;
6596
tfarina42834112016-09-22 13:38:206597 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566598 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6599
6600 EXPECT_THAT(callback.GetResult(rv), IsOk());
6601
bnc691fda62016-08-12 00:43:166602 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566603 ASSERT_TRUE(response);
6604 EXPECT_TRUE(response->headers);
6605 std::string status_line = response->headers->GetStatusLine();
6606 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6607
6608 // Make memory critical notification and ensure the transaction still has been
6609 // operating right.
6610 base::MemoryPressureListener::NotifyMemoryPressure(
6611 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6612 base::RunLoop().RunUntilIdle();
6613
6614 // Socket should not be flushed as long as it is not idle.
6615 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6616
6617 std::string response_data;
bnc691fda62016-08-12 00:43:166618 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566619 EXPECT_THAT(rv, IsOk());
6620 EXPECT_EQ("hello world", response_data);
6621
6622 // Empty the current queue. This is necessary because idle sockets are
6623 // added to the connection pool asynchronously with a PostTask.
6624 base::RunLoop().RunUntilIdle();
6625
6626 // We now check to make sure the socket was added back to the pool.
6627 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6628
6629 // Idle sockets should be flushed now.
6630 base::MemoryPressureListener::NotifyMemoryPressure(
6631 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6632 base::RunLoop().RunUntilIdle();
6633
6634 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6635}
6636
6637// Grab an SSL socket, use it, and put it back into the pool. Then, make
6638// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016639TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566640 HttpRequestInfo request;
6641 request.method = "GET";
6642 request.url = GURL("https://www.example.org/");
6643 request.load_flags = 0;
6644
6645 MockWrite data_writes[] = {
6646 MockWrite("GET / HTTP/1.1\r\n"
6647 "Host: www.example.org\r\n"
6648 "Connection: keep-alive\r\n\r\n"),
6649 };
6650
6651 MockRead data_reads[] = {
6652 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6653 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6654
6655 SSLSocketDataProvider ssl(ASYNC, OK);
6656 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6657
6658 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6659 arraysize(data_writes));
6660 session_deps_.socket_factory->AddSocketDataProvider(&data);
6661
6662 TestCompletionCallback callback;
6663
6664 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166665 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566666
6667 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206668 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566669
6670 EXPECT_THAT(callback.GetResult(rv), IsOk());
6671
bnc691fda62016-08-12 00:43:166672 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566673 ASSERT_TRUE(response);
6674 ASSERT_TRUE(response->headers);
6675 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6676
6677 // Make memory critical notification and ensure the transaction still has been
6678 // operating right.
6679 base::MemoryPressureListener::NotifyMemoryPressure(
6680 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6681 base::RunLoop().RunUntilIdle();
6682
6683 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6684
6685 std::string response_data;
bnc691fda62016-08-12 00:43:166686 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566687 EXPECT_THAT(rv, IsOk());
6688 EXPECT_EQ("hello world", response_data);
6689
6690 // Empty the current queue. This is necessary because idle sockets are
6691 // added to the connection pool asynchronously with a PostTask.
6692 base::RunLoop().RunUntilIdle();
6693
6694 // We now check to make sure the socket was added back to the pool.
6695 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6696
6697 // Make memory notification once again and ensure idle socket is closed.
6698 base::MemoryPressureListener::NotifyMemoryPressure(
6699 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6700 base::RunLoop().RunUntilIdle();
6701
6702 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6703}
6704
[email protected]b4404c02009-04-10 16:38:526705// Make sure that we recycle a socket after a zero-length response.
6706// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016707TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426708 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526709 request.method = "GET";
bncce36dca22015-04-21 22:11:236710 request.url = GURL(
6711 "http://www.example.org/csi?v=3&s=web&action=&"
6712 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6713 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6714 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526715
danakj1fd259a02016-04-16 03:17:096716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276717
[email protected]b4404c02009-04-10 16:38:526718 MockRead data_reads[] = {
6719 MockRead("HTTP/1.1 204 No Content\r\n"
6720 "Content-Length: 0\r\n"
6721 "Content-Type: text/html\r\n\r\n"),
6722 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066723 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526724 };
6725
[email protected]31a2bfe2010-02-09 08:03:396726 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076727 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526728
mmenkecc2298e2015-12-07 18:20:186729 // Transaction must be created after the MockReads, so it's destroyed before
6730 // them.
bnc691fda62016-08-12 00:43:166731 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186732
[email protected]49639fa2011-12-20 23:22:416733 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526734
tfarina42834112016-09-22 13:38:206735 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526737
6738 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016739 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526740
bnc691fda62016-08-12 00:43:166741 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526742 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526743
wezca1070932016-05-26 20:30:526744 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526745 std::string status_line = response->headers->GetStatusLine();
6746 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6747
[email protected]90499482013-06-01 00:39:506748 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526749
6750 std::string response_data;
bnc691fda62016-08-12 00:43:166751 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016752 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526753 EXPECT_EQ("", response_data);
6754
6755 // Empty the current queue. This is necessary because idle sockets are
6756 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556757 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526758
6759 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506760 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526761}
6762
bncd16676a2016-07-20 16:23:016763TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096764 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226765 element_readers.push_back(
ricea2deef682016-09-09 08:04:076766 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226767 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276768
[email protected]1c773ea12009-04-28 19:58:426769 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516770 // Transaction 1: a GET request that succeeds. The socket is recycled
6771 // after use.
6772 request[0].method = "GET";
6773 request[0].url = GURL("http://www.google.com/");
6774 request[0].load_flags = 0;
6775 // Transaction 2: a POST request. Reuses the socket kept alive from
6776 // transaction 1. The first attempts fails when writing the POST data.
6777 // This causes the transaction to retry with a new socket. The second
6778 // attempt succeeds.
6779 request[1].method = "POST";
6780 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276781 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516782 request[1].load_flags = 0;
6783
danakj1fd259a02016-04-16 03:17:096784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516785
6786 // The first socket is used for transaction 1 and the first attempt of
6787 // transaction 2.
6788
6789 // The response of transaction 1.
6790 MockRead data_reads1[] = {
6791 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6792 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066793 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516794 };
6795 // The mock write results of transaction 1 and the first attempt of
6796 // transaction 2.
6797 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066798 MockWrite(SYNCHRONOUS, 64), // GET
6799 MockWrite(SYNCHRONOUS, 93), // POST
6800 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516801 };
[email protected]31a2bfe2010-02-09 08:03:396802 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6803 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516804
6805 // The second socket is used for the second attempt of transaction 2.
6806
6807 // The response of transaction 2.
6808 MockRead data_reads2[] = {
6809 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6810 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066811 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516812 };
6813 // The mock write results of the second attempt of transaction 2.
6814 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066815 MockWrite(SYNCHRONOUS, 93), // POST
6816 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516817 };
[email protected]31a2bfe2010-02-09 08:03:396818 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6819 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516820
[email protected]bb88e1d32013-05-03 23:11:076821 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6822 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516823
thestig9d3bb0c2015-01-24 00:49:516824 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516825 "hello world", "welcome"
6826 };
6827
6828 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516830
[email protected]49639fa2011-12-20 23:22:416831 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516832
tfarina42834112016-09-22 13:38:206833 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516835
6836 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016837 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516838
bnc691fda62016-08-12 00:43:166839 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526840 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516841
wezca1070932016-05-26 20:30:526842 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516843 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6844
6845 std::string response_data;
bnc691fda62016-08-12 00:43:166846 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016847 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516848 EXPECT_EQ(kExpectedResponseData[i], response_data);
6849 }
6850}
[email protected]f9ee6b52008-11-08 06:46:236851
6852// Test the request-challenge-retry sequence for basic auth when there is
6853// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166854// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016855TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426856 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236857 request.method = "GET";
bncce36dca22015-04-21 22:11:236858 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416859 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296860
danakj1fd259a02016-04-16 03:17:096861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276863
[email protected]a97cca42009-08-14 01:00:296864 // The password contains an escaped character -- for this test to pass it
6865 // will need to be unescaped by HttpNetworkTransaction.
6866 EXPECT_EQ("b%40r", request.url.password());
6867
[email protected]f9ee6b52008-11-08 06:46:236868 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236869 MockWrite(
6870 "GET / HTTP/1.1\r\n"
6871 "Host: www.example.org\r\n"
6872 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236873 };
6874
6875 MockRead data_reads1[] = {
6876 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6877 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6878 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066879 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236880 };
6881
[email protected]2262e3a2012-05-22 16:08:166882 // After the challenge above, the transaction will be restarted using the
6883 // identity from the url (foo, b@r) to answer the challenge.
6884 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236885 MockWrite(
6886 "GET / HTTP/1.1\r\n"
6887 "Host: www.example.org\r\n"
6888 "Connection: keep-alive\r\n"
6889 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166890 };
6891
6892 MockRead data_reads2[] = {
6893 MockRead("HTTP/1.0 200 OK\r\n"),
6894 MockRead("Content-Length: 100\r\n\r\n"),
6895 MockRead(SYNCHRONOUS, OK),
6896 };
6897
[email protected]31a2bfe2010-02-09 08:03:396898 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6899 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166900 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6901 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076902 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6903 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236904
[email protected]49639fa2011-12-20 23:22:416905 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206906 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236908 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016909 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166910 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166911
6912 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166913 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016914 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166915 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016916 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166917 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226918
bnc691fda62016-08-12 00:43:166919 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526920 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166921
6922 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526923 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166924
6925 EXPECT_EQ(100, response->headers->GetContentLength());
6926
6927 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556928 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166929}
6930
6931// Test the request-challenge-retry sequence for basic auth when there is an
6932// incorrect identity in the URL. The identity from the URL should be used only
6933// once.
bncd16676a2016-07-20 16:23:016934TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166935 HttpRequestInfo request;
6936 request.method = "GET";
6937 // Note: the URL has a username:password in it. The password "baz" is
6938 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236939 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166940
6941 request.load_flags = LOAD_NORMAL;
6942
danakj1fd259a02016-04-16 03:17:096943 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166944 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166945
6946 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236947 MockWrite(
6948 "GET / HTTP/1.1\r\n"
6949 "Host: www.example.org\r\n"
6950 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166951 };
6952
6953 MockRead data_reads1[] = {
6954 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6955 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6956 MockRead("Content-Length: 10\r\n\r\n"),
6957 MockRead(SYNCHRONOUS, ERR_FAILED),
6958 };
6959
6960 // After the challenge above, the transaction will be restarted using the
6961 // identity from the url (foo, baz) to answer the challenge.
6962 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236963 MockWrite(
6964 "GET / HTTP/1.1\r\n"
6965 "Host: www.example.org\r\n"
6966 "Connection: keep-alive\r\n"
6967 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166968 };
6969
6970 MockRead data_reads2[] = {
6971 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6972 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6973 MockRead("Content-Length: 10\r\n\r\n"),
6974 MockRead(SYNCHRONOUS, ERR_FAILED),
6975 };
6976
6977 // After the challenge above, the transaction will be restarted using the
6978 // identity supplied by the user (foo, bar) to answer the challenge.
6979 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236980 MockWrite(
6981 "GET / HTTP/1.1\r\n"
6982 "Host: www.example.org\r\n"
6983 "Connection: keep-alive\r\n"
6984 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166985 };
6986
6987 MockRead data_reads3[] = {
6988 MockRead("HTTP/1.0 200 OK\r\n"),
6989 MockRead("Content-Length: 100\r\n\r\n"),
6990 MockRead(SYNCHRONOUS, OK),
6991 };
6992
6993 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6994 data_writes1, arraysize(data_writes1));
6995 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6996 data_writes2, arraysize(data_writes2));
6997 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6998 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076999 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7000 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7001 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167002
7003 TestCompletionCallback callback1;
7004
tfarina42834112016-09-22 13:38:207005 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167007
7008 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017009 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167010
bnc691fda62016-08-12 00:43:167011 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167012 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167013 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167015 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017016 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167017 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167018
bnc691fda62016-08-12 00:43:167019 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527020 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167021 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7022
7023 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167024 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017025 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167026 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017027 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167028 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167029
bnc691fda62016-08-12 00:43:167030 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527031 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167032
7033 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527034 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167035
7036 EXPECT_EQ(100, response->headers->GetContentLength());
7037
[email protected]ea9dc9a2009-09-05 00:43:327038 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557039 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327040}
7041
[email protected]2217aa22013-10-11 03:03:547042
7043// Test the request-challenge-retry sequence for basic auth when there is a
7044// correct identity in the URL, but its use is being suppressed. The identity
7045// from the URL should never be used.
bncd16676a2016-07-20 16:23:017046TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547047 HttpRequestInfo request;
7048 request.method = "GET";
bncce36dca22015-04-21 22:11:237049 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547050 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7051
danakj1fd259a02016-04-16 03:17:097052 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167053 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547054
7055 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237056 MockWrite(
7057 "GET / HTTP/1.1\r\n"
7058 "Host: www.example.org\r\n"
7059 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547060 };
7061
7062 MockRead data_reads1[] = {
7063 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7064 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7065 MockRead("Content-Length: 10\r\n\r\n"),
7066 MockRead(SYNCHRONOUS, ERR_FAILED),
7067 };
7068
7069 // After the challenge above, the transaction will be restarted using the
7070 // identity supplied by the user, not the one in the URL, to answer the
7071 // challenge.
7072 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237073 MockWrite(
7074 "GET / HTTP/1.1\r\n"
7075 "Host: www.example.org\r\n"
7076 "Connection: keep-alive\r\n"
7077 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547078 };
7079
7080 MockRead data_reads3[] = {
7081 MockRead("HTTP/1.0 200 OK\r\n"),
7082 MockRead("Content-Length: 100\r\n\r\n"),
7083 MockRead(SYNCHRONOUS, OK),
7084 };
7085
7086 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7087 data_writes1, arraysize(data_writes1));
7088 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7089 data_writes3, arraysize(data_writes3));
7090 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7091 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7092
7093 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207094 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547096 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017097 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167098 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547099
bnc691fda62016-08-12 00:43:167100 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527101 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547102 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7103
7104 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167105 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547107 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017108 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167109 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547110
bnc691fda62016-08-12 00:43:167111 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527112 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547113
7114 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527115 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547116 EXPECT_EQ(100, response->headers->GetContentLength());
7117
7118 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557119 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547120}
7121
[email protected]f9ee6b52008-11-08 06:46:237122// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017123TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237125
7126 // Transaction 1: authenticate (foo, bar) on MyRealm1
7127 {
[email protected]1c773ea12009-04-28 19:58:427128 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237129 request.method = "GET";
bncce36dca22015-04-21 22:11:237130 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237131
bnc691fda62016-08-12 00:43:167132 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277133
[email protected]f9ee6b52008-11-08 06:46:237134 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237135 MockWrite(
7136 "GET /x/y/z HTTP/1.1\r\n"
7137 "Host: www.example.org\r\n"
7138 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237139 };
7140
7141 MockRead data_reads1[] = {
7142 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7143 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7144 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067145 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237146 };
7147
7148 // Resend with authorization (username=foo, password=bar)
7149 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237150 MockWrite(
7151 "GET /x/y/z HTTP/1.1\r\n"
7152 "Host: www.example.org\r\n"
7153 "Connection: keep-alive\r\n"
7154 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237155 };
7156
7157 // Sever accepts the authorization.
7158 MockRead data_reads2[] = {
7159 MockRead("HTTP/1.0 200 OK\r\n"),
7160 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067161 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237162 };
7163
[email protected]31a2bfe2010-02-09 08:03:397164 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7165 data_writes1, arraysize(data_writes1));
7166 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7167 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077168 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7169 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237170
[email protected]49639fa2011-12-20 23:22:417171 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237172
tfarina42834112016-09-22 13:38:207173 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237175
7176 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017177 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237178
bnc691fda62016-08-12 00:43:167179 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527180 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047181 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[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(kFoo, kBar),
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 2: authenticate (foo2, bar2) on MyRealm2
7201 {
[email protected]1c773ea12009-04-28 19:58:427202 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237203 request.method = "GET";
7204 // Note that Transaction 1 was at /x/y/z, so this is in the same
7205 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237206 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237207
bnc691fda62016-08-12 00:43:167208 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277209
[email protected]f9ee6b52008-11-08 06:46:237210 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237211 MockWrite(
7212 "GET /x/y/a/b HTTP/1.1\r\n"
7213 "Host: www.example.org\r\n"
7214 "Connection: keep-alive\r\n"
7215 // Send preemptive authorization for MyRealm1
7216 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237217 };
7218
7219 // The server didn't like the preemptive authorization, and
7220 // challenges us for a different realm (MyRealm2).
7221 MockRead data_reads1[] = {
7222 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7223 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7224 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067225 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237226 };
7227
7228 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7229 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237230 MockWrite(
7231 "GET /x/y/a/b HTTP/1.1\r\n"
7232 "Host: www.example.org\r\n"
7233 "Connection: keep-alive\r\n"
7234 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237235 };
7236
7237 // Sever accepts the authorization.
7238 MockRead data_reads2[] = {
7239 MockRead("HTTP/1.0 200 OK\r\n"),
7240 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067241 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237242 };
7243
[email protected]31a2bfe2010-02-09 08:03:397244 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7245 data_writes1, arraysize(data_writes1));
7246 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7247 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077248 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7249 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237250
[email protected]49639fa2011-12-20 23:22:417251 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237252
tfarina42834112016-09-22 13:38:207253 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237255
7256 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017257 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237258
bnc691fda62016-08-12 00:43:167259 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527260 ASSERT_TRUE(response);
7261 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047262 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437263 EXPECT_EQ("http://www.example.org",
7264 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047265 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197266 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237267
[email protected]49639fa2011-12-20 23:22:417268 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237269
bnc691fda62016-08-12 00:43:167270 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7271 callback2.callback());
robpercival214763f2016-07-01 23:27:017272 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237273
7274 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017275 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237276
bnc691fda62016-08-12 00:43:167277 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527278 ASSERT_TRUE(response);
7279 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237280 EXPECT_EQ(100, response->headers->GetContentLength());
7281 }
7282
7283 // ------------------------------------------------------------------------
7284
7285 // Transaction 3: Resend a request in MyRealm's protection space --
7286 // succeed with preemptive authorization.
7287 {
[email protected]1c773ea12009-04-28 19:58:427288 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237289 request.method = "GET";
bncce36dca22015-04-21 22:11:237290 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237291
bnc691fda62016-08-12 00:43:167292 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277293
[email protected]f9ee6b52008-11-08 06:46:237294 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237295 MockWrite(
7296 "GET /x/y/z2 HTTP/1.1\r\n"
7297 "Host: www.example.org\r\n"
7298 "Connection: keep-alive\r\n"
7299 // The authorization for MyRealm1 gets sent preemptively
7300 // (since the url is in the same protection space)
7301 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237302 };
7303
7304 // Sever accepts the preemptive authorization
7305 MockRead data_reads1[] = {
7306 MockRead("HTTP/1.0 200 OK\r\n"),
7307 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067308 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237309 };
7310
[email protected]31a2bfe2010-02-09 08:03:397311 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7312 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077313 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237314
[email protected]49639fa2011-12-20 23:22:417315 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237316
tfarina42834112016-09-22 13:38:207317 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237319
7320 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017321 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237322
bnc691fda62016-08-12 00:43:167323 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527324 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237325
wezca1070932016-05-26 20:30:527326 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237327 EXPECT_EQ(100, response->headers->GetContentLength());
7328 }
7329
7330 // ------------------------------------------------------------------------
7331
7332 // Transaction 4: request another URL in MyRealm (however the
7333 // url is not known to belong to the protection space, so no pre-auth).
7334 {
[email protected]1c773ea12009-04-28 19:58:427335 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237336 request.method = "GET";
bncce36dca22015-04-21 22:11:237337 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237338
bnc691fda62016-08-12 00:43:167339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277340
[email protected]f9ee6b52008-11-08 06:46:237341 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237342 MockWrite(
7343 "GET /x/1 HTTP/1.1\r\n"
7344 "Host: www.example.org\r\n"
7345 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237346 };
7347
7348 MockRead data_reads1[] = {
7349 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7350 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7351 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067352 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237353 };
7354
7355 // Resend with authorization from MyRealm's cache.
7356 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237357 MockWrite(
7358 "GET /x/1 HTTP/1.1\r\n"
7359 "Host: www.example.org\r\n"
7360 "Connection: keep-alive\r\n"
7361 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237362 };
7363
7364 // Sever accepts the authorization.
7365 MockRead data_reads2[] = {
7366 MockRead("HTTP/1.0 200 OK\r\n"),
7367 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067368 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237369 };
7370
[email protected]31a2bfe2010-02-09 08:03:397371 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7372 data_writes1, arraysize(data_writes1));
7373 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7374 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077375 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7376 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237377
[email protected]49639fa2011-12-20 23:22:417378 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237379
tfarina42834112016-09-22 13:38:207380 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017381 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237382
7383 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017384 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237385
bnc691fda62016-08-12 00:43:167386 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417387 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167388 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227390 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017391 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167392 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227393
bnc691fda62016-08-12 00:43:167394 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527395 ASSERT_TRUE(response);
7396 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237397 EXPECT_EQ(100, response->headers->GetContentLength());
7398 }
7399
7400 // ------------------------------------------------------------------------
7401
7402 // Transaction 5: request a URL in MyRealm, but the server rejects the
7403 // cached identity. Should invalidate and re-prompt.
7404 {
[email protected]1c773ea12009-04-28 19:58:427405 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237406 request.method = "GET";
bncce36dca22015-04-21 22:11:237407 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237408
bnc691fda62016-08-12 00:43:167409 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277410
[email protected]f9ee6b52008-11-08 06:46:237411 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237412 MockWrite(
7413 "GET /p/q/t HTTP/1.1\r\n"
7414 "Host: www.example.org\r\n"
7415 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237416 };
7417
7418 MockRead data_reads1[] = {
7419 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7420 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7421 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067422 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237423 };
7424
7425 // Resend with authorization from cache for MyRealm.
7426 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237427 MockWrite(
7428 "GET /p/q/t HTTP/1.1\r\n"
7429 "Host: www.example.org\r\n"
7430 "Connection: keep-alive\r\n"
7431 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237432 };
7433
7434 // Sever rejects the authorization.
7435 MockRead data_reads2[] = {
7436 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7437 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7438 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067439 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237440 };
7441
7442 // At this point we should prompt for new credentials for MyRealm.
7443 // Restart with username=foo3, password=foo4.
7444 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237445 MockWrite(
7446 "GET /p/q/t HTTP/1.1\r\n"
7447 "Host: www.example.org\r\n"
7448 "Connection: keep-alive\r\n"
7449 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237450 };
7451
7452 // Sever accepts the authorization.
7453 MockRead data_reads3[] = {
7454 MockRead("HTTP/1.0 200 OK\r\n"),
7455 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067456 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237457 };
7458
[email protected]31a2bfe2010-02-09 08:03:397459 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7460 data_writes1, arraysize(data_writes1));
7461 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7462 data_writes2, arraysize(data_writes2));
7463 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7464 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077465 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7466 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7467 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237468
[email protected]49639fa2011-12-20 23:22:417469 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237470
tfarina42834112016-09-22 13:38:207471 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237473
7474 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017475 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237476
bnc691fda62016-08-12 00:43:167477 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417478 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167479 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227481 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017482 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167483 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227484
bnc691fda62016-08-12 00:43:167485 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527486 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047487 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237488
[email protected]49639fa2011-12-20 23:22:417489 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237490
bnc691fda62016-08-12 00:43:167491 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7492 callback3.callback());
robpercival214763f2016-07-01 23:27:017493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237494
[email protected]0757e7702009-03-27 04:00:227495 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017496 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237497
bnc691fda62016-08-12 00:43:167498 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527499 ASSERT_TRUE(response);
7500 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237501 EXPECT_EQ(100, response->headers->GetContentLength());
7502 }
7503}
[email protected]89ceba9a2009-03-21 03:46:067504
[email protected]3c32c5f2010-05-18 15:18:127505// Tests that nonce count increments when multiple auth attempts
7506// are started with the same nonce.
bncd16676a2016-07-20 16:23:017507TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447508 HttpAuthHandlerDigest::Factory* digest_factory =
7509 new HttpAuthHandlerDigest::Factory();
7510 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7511 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7512 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077513 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097514 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127515
7516 // Transaction 1: authenticate (foo, bar) on MyRealm1
7517 {
[email protected]3c32c5f2010-05-18 15:18:127518 HttpRequestInfo request;
7519 request.method = "GET";
bncce36dca22015-04-21 22:11:237520 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127521
bnc691fda62016-08-12 00:43:167522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277523
[email protected]3c32c5f2010-05-18 15:18:127524 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237525 MockWrite(
7526 "GET /x/y/z HTTP/1.1\r\n"
7527 "Host: www.example.org\r\n"
7528 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127529 };
7530
7531 MockRead data_reads1[] = {
7532 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7533 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7534 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067535 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127536 };
7537
7538 // Resend with authorization (username=foo, password=bar)
7539 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237540 MockWrite(
7541 "GET /x/y/z HTTP/1.1\r\n"
7542 "Host: www.example.org\r\n"
7543 "Connection: keep-alive\r\n"
7544 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7545 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7546 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7547 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127548 };
7549
7550 // Sever accepts the authorization.
7551 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087552 MockRead("HTTP/1.0 200 OK\r\n"),
7553 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127554 };
7555
7556 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7557 data_writes1, arraysize(data_writes1));
7558 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7559 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077560 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7561 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127562
[email protected]49639fa2011-12-20 23:22:417563 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127564
tfarina42834112016-09-22 13:38:207565 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127567
7568 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017569 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127570
bnc691fda62016-08-12 00:43:167571 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527572 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047573 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127574
[email protected]49639fa2011-12-20 23:22:417575 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127576
bnc691fda62016-08-12 00:43:167577 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7578 callback2.callback());
robpercival214763f2016-07-01 23:27:017579 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127580
7581 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017582 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127583
bnc691fda62016-08-12 00:43:167584 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527585 ASSERT_TRUE(response);
7586 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127587 }
7588
7589 // ------------------------------------------------------------------------
7590
7591 // Transaction 2: Request another resource in digestive's protection space.
7592 // This will preemptively add an Authorization header which should have an
7593 // "nc" value of 2 (as compared to 1 in the first use.
7594 {
[email protected]3c32c5f2010-05-18 15:18:127595 HttpRequestInfo request;
7596 request.method = "GET";
7597 // Note that Transaction 1 was at /x/y/z, so this is in the same
7598 // protection space as digest.
bncce36dca22015-04-21 22:11:237599 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127600
bnc691fda62016-08-12 00:43:167601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277602
[email protected]3c32c5f2010-05-18 15:18:127603 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237604 MockWrite(
7605 "GET /x/y/a/b HTTP/1.1\r\n"
7606 "Host: www.example.org\r\n"
7607 "Connection: keep-alive\r\n"
7608 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7609 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7610 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7611 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127612 };
7613
7614 // Sever accepts the authorization.
7615 MockRead data_reads1[] = {
7616 MockRead("HTTP/1.0 200 OK\r\n"),
7617 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067618 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127619 };
7620
7621 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7622 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077623 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127624
[email protected]49639fa2011-12-20 23:22:417625 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127626
tfarina42834112016-09-22 13:38:207627 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127629
7630 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017631 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127632
bnc691fda62016-08-12 00:43:167633 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527634 ASSERT_TRUE(response);
7635 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127636 }
7637}
7638
[email protected]89ceba9a2009-03-21 03:46:067639// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017640TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067641 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067644
7645 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167646 trans.read_buf_ = new IOBuffer(15);
7647 trans.read_buf_len_ = 15;
7648 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067649
7650 // Setup state in response_
bnc691fda62016-08-12 00:43:167651 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577652 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087653 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577654 response->response_time = base::Time::Now();
7655 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067656
7657 { // Setup state for response_.vary_data
7658 HttpRequestInfo request;
7659 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7660 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277661 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437662 request.extra_headers.SetHeader("Foo", "1");
7663 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507664 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067665 }
7666
7667 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167668 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067669
7670 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167671 EXPECT_FALSE(trans.read_buf_);
7672 EXPECT_EQ(0, trans.read_buf_len_);
7673 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527674 EXPECT_FALSE(response->auth_challenge);
7675 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047676 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087677 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577678 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067679}
7680
[email protected]bacff652009-03-31 17:50:337681// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017682TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337683 HttpRequestInfo request;
7684 request.method = "GET";
bncce36dca22015-04-21 22:11:237685 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337686
danakj1fd259a02016-04-16 03:17:097687 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277689
[email protected]bacff652009-03-31 17:50:337690 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237691 MockWrite(
7692 "GET / HTTP/1.1\r\n"
7693 "Host: www.example.org\r\n"
7694 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337695 };
7696
7697 MockRead data_reads[] = {
7698 MockRead("HTTP/1.0 200 OK\r\n"),
7699 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7700 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067701 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337702 };
7703
[email protected]5ecc992a42009-11-11 01:41:597704 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397705 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7706 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067707 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7708 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337709
[email protected]bb88e1d32013-05-03 23:11:077710 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7711 session_deps_.socket_factory->AddSocketDataProvider(&data);
7712 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337714
[email protected]49639fa2011-12-20 23:22:417715 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337716
tfarina42834112016-09-22 13:38:207717 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337719
7720 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017721 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337722
bnc691fda62016-08-12 00:43:167723 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337725
7726 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017727 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337728
bnc691fda62016-08-12 00:43:167729 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337730
wezca1070932016-05-26 20:30:527731 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337732 EXPECT_EQ(100, response->headers->GetContentLength());
7733}
7734
7735// Test HTTPS connections to a site with a bad certificate, going through a
7736// proxy
bncd16676a2016-07-20 16:23:017737TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037738 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337739
7740 HttpRequestInfo request;
7741 request.method = "GET";
bncce36dca22015-04-21 22:11:237742 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337743
7744 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177745 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7746 "Host: www.example.org:443\r\n"
7747 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337748 };
7749
7750 MockRead proxy_reads[] = {
7751 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067752 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337753 };
7754
7755 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177756 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7757 "Host: www.example.org:443\r\n"
7758 "Proxy-Connection: keep-alive\r\n\r\n"),
7759 MockWrite("GET / HTTP/1.1\r\n"
7760 "Host: www.example.org\r\n"
7761 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337762 };
7763
7764 MockRead data_reads[] = {
7765 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7766 MockRead("HTTP/1.0 200 OK\r\n"),
7767 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7768 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067769 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337770 };
7771
[email protected]31a2bfe2010-02-09 08:03:397772 StaticSocketDataProvider ssl_bad_certificate(
7773 proxy_reads, arraysize(proxy_reads),
7774 proxy_writes, arraysize(proxy_writes));
7775 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7776 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067777 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337779
[email protected]bb88e1d32013-05-03 23:11:077780 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7781 session_deps_.socket_factory->AddSocketDataProvider(&data);
7782 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337784
[email protected]49639fa2011-12-20 23:22:417785 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337786
7787 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077788 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337789
danakj1fd259a02016-04-16 03:17:097790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337792
tfarina42834112016-09-22 13:38:207793 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337795
7796 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017797 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337798
bnc691fda62016-08-12 00:43:167799 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337801
7802 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017803 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337804
bnc691fda62016-08-12 00:43:167805 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337806
wezca1070932016-05-26 20:30:527807 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337808 EXPECT_EQ(100, response->headers->GetContentLength());
7809 }
7810}
7811
[email protected]2df19bb2010-08-25 20:13:467812
7813// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017814TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037815 session_deps_.proxy_service =
7816 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517817 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077818 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467819
7820 HttpRequestInfo request;
7821 request.method = "GET";
bncce36dca22015-04-21 22:11:237822 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467823
7824 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177825 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7826 "Host: www.example.org:443\r\n"
7827 "Proxy-Connection: keep-alive\r\n\r\n"),
7828 MockWrite("GET / HTTP/1.1\r\n"
7829 "Host: www.example.org\r\n"
7830 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467831 };
7832
7833 MockRead data_reads[] = {
7834 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7835 MockRead("HTTP/1.1 200 OK\r\n"),
7836 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7837 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067838 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467839 };
7840
7841 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7842 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067843 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7844 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467845
[email protected]bb88e1d32013-05-03 23:11:077846 session_deps_.socket_factory->AddSocketDataProvider(&data);
7847 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7848 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467849
[email protected]49639fa2011-12-20 23:22:417850 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467851
danakj1fd259a02016-04-16 03:17:097852 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167853 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467854
tfarina42834112016-09-22 13:38:207855 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467857
7858 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017859 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167860 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467861
wezca1070932016-05-26 20:30:527862 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467863
tbansal2ecbbc72016-10-06 17:15:477864 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467865 EXPECT_TRUE(response->headers->IsKeepAlive());
7866 EXPECT_EQ(200, response->headers->response_code());
7867 EXPECT_EQ(100, response->headers->GetContentLength());
7868 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207869
7870 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167871 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207872 TestLoadTimingNotReusedWithPac(load_timing_info,
7873 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467874}
7875
[email protected]511f6f52010-12-17 03:58:297876// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017877TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037878 session_deps_.proxy_service =
7879 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517880 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077881 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297882
7883 HttpRequestInfo request;
7884 request.method = "GET";
bncce36dca22015-04-21 22:11:237885 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297886
7887 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177888 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7889 "Host: www.example.org:443\r\n"
7890 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297891 };
7892
7893 MockRead data_reads[] = {
7894 MockRead("HTTP/1.1 302 Redirect\r\n"),
7895 MockRead("Location: http://login.example.com/\r\n"),
7896 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067897 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297898 };
7899
7900 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7901 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067902 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297903
[email protected]bb88e1d32013-05-03 23:11:077904 session_deps_.socket_factory->AddSocketDataProvider(&data);
7905 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297906
[email protected]49639fa2011-12-20 23:22:417907 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297908
danakj1fd259a02016-04-16 03:17:097909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167910 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297911
tfarina42834112016-09-22 13:38:207912 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297914
7915 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017916 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167917 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297918
wezca1070932016-05-26 20:30:527919 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297920
7921 EXPECT_EQ(302, response->headers->response_code());
7922 std::string url;
7923 EXPECT_TRUE(response->headers->IsRedirect(&url));
7924 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207925
7926 // In the case of redirects from proxies, HttpNetworkTransaction returns
7927 // timing for the proxy connection instead of the connection to the host,
7928 // and no send / receive times.
7929 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7930 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167931 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207932
7933 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197934 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207935
7936 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7937 EXPECT_LE(load_timing_info.proxy_resolve_start,
7938 load_timing_info.proxy_resolve_end);
7939 EXPECT_LE(load_timing_info.proxy_resolve_end,
7940 load_timing_info.connect_timing.connect_start);
7941 ExpectConnectTimingHasTimes(
7942 load_timing_info.connect_timing,
7943 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7944
7945 EXPECT_TRUE(load_timing_info.send_start.is_null());
7946 EXPECT_TRUE(load_timing_info.send_end.is_null());
7947 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297948}
7949
7950// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017951TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037952 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297953
7954 HttpRequestInfo request;
7955 request.method = "GET";
bncce36dca22015-04-21 22:11:237956 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297957
bncdf80d44fd2016-07-15 20:27:417958 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237959 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417960 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:087961 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297962 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417963 CreateMockWrite(conn, 0, SYNCHRONOUS),
7964 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297965 };
7966
7967 static const char* const kExtraHeaders[] = {
7968 "location",
7969 "http://login.example.com/",
7970 };
bnc42331402016-07-25 13:36:157971 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237972 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297973 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417974 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297975 };
7976
rch8e6c6c42015-05-01 14:05:137977 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7978 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067979 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367980 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297981
[email protected]bb88e1d32013-05-03 23:11:077982 session_deps_.socket_factory->AddSocketDataProvider(&data);
7983 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297984
[email protected]49639fa2011-12-20 23:22:417985 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297986
danakj1fd259a02016-04-16 03:17:097987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297989
tfarina42834112016-09-22 13:38:207990 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017991 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297992
7993 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017994 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167995 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297996
wezca1070932016-05-26 20:30:527997 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297998
7999 EXPECT_EQ(302, response->headers->response_code());
8000 std::string url;
8001 EXPECT_TRUE(response->headers->IsRedirect(&url));
8002 EXPECT_EQ("http://login.example.com/", url);
8003}
8004
[email protected]4eddbc732012-08-09 05:40:178005// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018006TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038007 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298008
8009 HttpRequestInfo request;
8010 request.method = "GET";
bncce36dca22015-04-21 22:11:238011 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298012
8013 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178014 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8015 "Host: www.example.org:443\r\n"
8016 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298017 };
8018
8019 MockRead data_reads[] = {
8020 MockRead("HTTP/1.1 404 Not Found\r\n"),
8021 MockRead("Content-Length: 23\r\n\r\n"),
8022 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068023 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298024 };
8025
8026 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8027 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068028 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298029
[email protected]bb88e1d32013-05-03 23:11:078030 session_deps_.socket_factory->AddSocketDataProvider(&data);
8031 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298032
[email protected]49639fa2011-12-20 23:22:418033 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298034
danakj1fd259a02016-04-16 03:17:098035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298037
tfarina42834112016-09-22 13:38:208038 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298040
8041 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018042 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298043
ttuttle960fcbf2016-04-19 13:26:328044 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298045}
8046
[email protected]4eddbc732012-08-09 05:40:178047// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018048TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038049 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298050
8051 HttpRequestInfo request;
8052 request.method = "GET";
bncce36dca22015-04-21 22:11:238053 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298054
bncdf80d44fd2016-07-15 20:27:418055 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238056 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418057 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088058 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298059 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418060 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298061 };
8062
8063 static const char* const kExtraHeaders[] = {
8064 "location",
8065 "http://login.example.com/",
8066 };
bnc42331402016-07-25 13:36:158067 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238068 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418069 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558070 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298071 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418072 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138073 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298074 };
8075
rch8e6c6c42015-05-01 14:05:138076 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8077 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068078 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368079 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298080
[email protected]bb88e1d32013-05-03 23:11:078081 session_deps_.socket_factory->AddSocketDataProvider(&data);
8082 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298083
[email protected]49639fa2011-12-20 23:22:418084 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298085
danakj1fd259a02016-04-16 03:17:098086 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298088
tfarina42834112016-09-22 13:38:208089 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298091
8092 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018093 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298094
ttuttle960fcbf2016-04-19 13:26:328095 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298096}
8097
[email protected]0c5fb722012-02-28 11:50:358098// Test the request-challenge-retry sequence for basic auth, through
8099// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018100TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358101 HttpRequestInfo request;
8102 request.method = "GET";
bncce36dca22015-04-21 22:11:238103 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358104 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298105 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358106
8107 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038108 session_deps_.proxy_service =
8109 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518110 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078111 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358113
8114 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418115 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238116 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418117 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088118 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388119 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358120
bnc691fda62016-08-12 00:43:168121 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358122 // be issuing -- the final header line contains the credentials.
8123 const char* const kAuthCredentials[] = {
8124 "proxy-authorization", "Basic Zm9vOmJhcg==",
8125 };
bncdf80d44fd2016-07-15 20:27:418126 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348127 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238128 HostPortPair("www.example.org", 443)));
8129 // fetch https://www.example.org/ via HTTP
8130 const char get[] =
8131 "GET / HTTP/1.1\r\n"
8132 "Host: www.example.org\r\n"
8133 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418134 SpdySerializedFrame wrapped_get(
8135 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358136
8137 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418138 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8139 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358140 };
8141
8142 // The proxy responds to the connect with a 407, using a persistent
8143 // connection.
thestig9d3bb0c2015-01-24 00:49:518144 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358145 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358146 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8147 };
bnc42331402016-07-25 13:36:158148 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418149 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358150
bnc42331402016-07-25 13:36:158151 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358152 const char resp[] = "HTTP/1.1 200 OK\r\n"
8153 "Content-Length: 5\r\n\r\n";
8154
bncdf80d44fd2016-07-15 20:27:418155 SpdySerializedFrame wrapped_get_resp(
8156 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8157 SpdySerializedFrame wrapped_body(
8158 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358159 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418160 CreateMockRead(conn_auth_resp, 1, ASYNC),
8161 CreateMockRead(conn_resp, 4, ASYNC),
8162 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8163 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138164 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358165 };
8166
rch8e6c6c42015-05-01 14:05:138167 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8168 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078169 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358170 // Negotiate SPDY to the proxy
8171 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368172 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078173 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358174 // Vanilla SSL to the server
8175 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078176 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358177
8178 TestCompletionCallback callback1;
8179
bnc87dcefc2017-05-25 12:47:588180 auto trans =
8181 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358182
8183 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358185
8186 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018187 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468188 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358189 log.GetEntries(&entries);
8190 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008191 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8192 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358193 ExpectLogContainsSomewhere(
8194 entries, pos,
mikecirone8b85c432016-09-08 19:11:008195 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8196 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358197
8198 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528199 ASSERT_TRUE(response);
8200 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358201 EXPECT_EQ(407, response->headers->response_code());
8202 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528203 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438204 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358205
8206 TestCompletionCallback callback2;
8207
8208 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8209 callback2.callback());
robpercival214763f2016-07-01 23:27:018210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358211
8212 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018213 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358214
8215 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528216 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358217
8218 EXPECT_TRUE(response->headers->IsKeepAlive());
8219 EXPECT_EQ(200, response->headers->response_code());
8220 EXPECT_EQ(5, response->headers->GetContentLength());
8221 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8222
8223 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528224 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358225
[email protected]029c83b62013-01-24 05:28:208226 LoadTimingInfo load_timing_info;
8227 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8228 TestLoadTimingNotReusedWithPac(load_timing_info,
8229 CONNECT_TIMING_HAS_SSL_TIMES);
8230
[email protected]0c5fb722012-02-28 11:50:358231 trans.reset();
8232 session->CloseAllConnections();
8233}
8234
[email protected]7c6f7ba2012-04-03 04:09:298235// Test that an explicitly trusted SPDY proxy can push a resource from an
8236// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018237TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158238 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588239 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158240 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8241 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298242 HttpRequestInfo request;
8243 HttpRequestInfo push_request;
8244
[email protected]7c6f7ba2012-04-03 04:09:298245 request.method = "GET";
bncce36dca22015-04-21 22:11:238246 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298247 push_request.method = "GET";
8248 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8249
tbansal28e68f82016-02-04 02:56:158250 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038251 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158252 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518253 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078254 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508255
inlinechan894515af2016-12-09 02:40:108256 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508257
danakj1fd259a02016-04-16 03:17:098258 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298259
bncdf80d44fd2016-07-15 20:27:418260 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458261 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358262 SpdySerializedFrame stream2_priority(
8263 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298264
8265 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418266 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358267 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298268 };
8269
bncdf80d44fd2016-07-15 20:27:418270 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158271 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298272
bncdf80d44fd2016-07-15 20:27:418273 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298274
bncdf80d44fd2016-07-15 20:27:418275 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558276 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438277 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418278 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8279 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298280
8281 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418282 CreateMockRead(stream1_reply, 1, ASYNC),
8283 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358284 CreateMockRead(stream1_body, 4, ASYNC),
8285 CreateMockRead(stream2_body, 5, ASYNC),
8286 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298287 };
8288
rch8e6c6c42015-05-01 14:05:138289 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8290 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078291 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298292 // Negotiate SPDY to the proxy
8293 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368294 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078295 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298296
bnc87dcefc2017-05-25 12:47:588297 auto trans =
8298 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298299 TestCompletionCallback callback;
8300 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018301 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298302
8303 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018304 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298305 const HttpResponseInfo* response = trans->GetResponseInfo();
8306
bnc87dcefc2017-05-25 12:47:588307 auto push_trans =
8308 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508309 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018310 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298311
8312 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018313 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298314 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8315
wezca1070932016-05-26 20:30:528316 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298317 EXPECT_TRUE(response->headers->IsKeepAlive());
8318
8319 EXPECT_EQ(200, response->headers->response_code());
8320 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8321
8322 std::string response_data;
8323 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018324 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298325 EXPECT_EQ("hello!", response_data);
8326
[email protected]029c83b62013-01-24 05:28:208327 LoadTimingInfo load_timing_info;
8328 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8329 TestLoadTimingNotReusedWithPac(load_timing_info,
8330 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8331
[email protected]7c6f7ba2012-04-03 04:09:298332 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528333 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298334 EXPECT_EQ(200, push_response->headers->response_code());
8335
8336 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018337 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298338 EXPECT_EQ("pushed", response_data);
8339
[email protected]029c83b62013-01-24 05:28:208340 LoadTimingInfo push_load_timing_info;
8341 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8342 TestLoadTimingReusedWithPac(push_load_timing_info);
8343 // The transactions should share a socket ID, despite being for different
8344 // origins.
8345 EXPECT_EQ(load_timing_info.socket_log_id,
8346 push_load_timing_info.socket_log_id);
8347
[email protected]7c6f7ba2012-04-03 04:09:298348 trans.reset();
8349 push_trans.reset();
8350 session->CloseAllConnections();
8351}
8352
[email protected]8c843192012-04-05 07:15:008353// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018354TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158355 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588356 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158357 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8358 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008359 HttpRequestInfo request;
8360
8361 request.method = "GET";
bncce36dca22015-04-21 22:11:238362 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008363
tbansal28e68f82016-02-04 02:56:158364 session_deps_.proxy_service =
8365 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518366 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078367 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508368
8369 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108370 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508371
danakj1fd259a02016-04-16 03:17:098372 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008373
bncdf80d44fd2016-07-15 20:27:418374 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458375 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008376
bncdf80d44fd2016-07-15 20:27:418377 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088378 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008379
8380 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418381 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008382 };
8383
bncdf80d44fd2016-07-15 20:27:418384 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158385 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008386
bncdf80d44fd2016-07-15 20:27:418387 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008388
bncdf80d44fd2016-07-15 20:27:418389 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558390 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008391
8392 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418393 CreateMockRead(stream1_reply, 1, ASYNC),
8394 CreateMockRead(stream2_syn, 2, ASYNC),
8395 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598396 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008397 };
8398
rch8e6c6c42015-05-01 14:05:138399 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8400 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078401 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008402 // Negotiate SPDY to the proxy
8403 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368404 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078405 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008406
bnc87dcefc2017-05-25 12:47:588407 auto trans =
8408 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008409 TestCompletionCallback callback;
8410 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008412
8413 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018414 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008415 const HttpResponseInfo* response = trans->GetResponseInfo();
8416
wezca1070932016-05-26 20:30:528417 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008418 EXPECT_TRUE(response->headers->IsKeepAlive());
8419
8420 EXPECT_EQ(200, response->headers->response_code());
8421 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8422
8423 std::string response_data;
8424 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018425 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008426 EXPECT_EQ("hello!", response_data);
8427
8428 trans.reset();
8429 session->CloseAllConnections();
8430}
8431
tbansal8ef1d3e2016-02-03 04:05:428432// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8433// resources.
bncd16676a2016-07-20 16:23:018434TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158435 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588436 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158437 proxy_delegate->set_trusted_spdy_proxy(
8438 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8439
tbansal8ef1d3e2016-02-03 04:05:428440 HttpRequestInfo request;
8441
8442 request.method = "GET";
8443 request.url = GURL("http://www.example.org/");
8444
8445 // Configure against https proxy server "myproxy:70".
8446 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8447 BoundTestNetLog log;
8448 session_deps_.net_log = log.bound().net_log();
8449
8450 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108451 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428452
danakj1fd259a02016-04-16 03:17:098453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428454
bncdf80d44fd2016-07-15 20:27:418455 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458456 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358457 SpdySerializedFrame stream2_priority(
8458 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428459
8460 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418461 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358462 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428463 };
8464
bncdf80d44fd2016-07-15 20:27:418465 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158466 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428467
bncdf80d44fd2016-07-15 20:27:418468 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:338469 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:498470
bncdf80d44fd2016-07-15 20:27:418471 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428472
bncdf80d44fd2016-07-15 20:27:418473 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158474 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428475
bncdf80d44fd2016-07-15 20:27:418476 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428477
8478 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418479 CreateMockRead(stream1_reply, 1, ASYNC),
8480 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358481 CreateMockRead(stream1_body, 4, ASYNC),
8482 CreateMockRead(stream2_body, 5, ASYNC),
8483 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428484 };
8485
8486 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8487 arraysize(spdy_writes));
8488 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8489 // Negotiate SPDY to the proxy
8490 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368491 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428492 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8493
bnc87dcefc2017-05-25 12:47:588494 auto trans =
8495 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428496 TestCompletionCallback callback;
8497 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428499
8500 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018501 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428502 const HttpResponseInfo* response = trans->GetResponseInfo();
8503
wezca1070932016-05-26 20:30:528504 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428505 EXPECT_TRUE(response->headers->IsKeepAlive());
8506
8507 EXPECT_EQ(200, response->headers->response_code());
8508 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8509
8510 std::string response_data;
8511 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018512 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428513 EXPECT_EQ("hello!", response_data);
8514
8515 trans.reset();
8516 session->CloseAllConnections();
8517}
8518
[email protected]2df19bb2010-08-25 20:13:468519// Test HTTPS connections to a site with a bad certificate, going through an
8520// HTTPS proxy
bncd16676a2016-07-20 16:23:018521TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038522 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468523
8524 HttpRequestInfo request;
8525 request.method = "GET";
bncce36dca22015-04-21 22:11:238526 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468527
8528 // Attempt to fetch the URL from a server with a bad cert
8529 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178530 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8531 "Host: www.example.org:443\r\n"
8532 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468533 };
8534
8535 MockRead bad_cert_reads[] = {
8536 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068537 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468538 };
8539
8540 // Attempt to fetch the URL with a good cert
8541 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178542 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8543 "Host: www.example.org:443\r\n"
8544 "Proxy-Connection: keep-alive\r\n\r\n"),
8545 MockWrite("GET / HTTP/1.1\r\n"
8546 "Host: www.example.org\r\n"
8547 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468548 };
8549
8550 MockRead good_cert_reads[] = {
8551 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8552 MockRead("HTTP/1.0 200 OK\r\n"),
8553 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8554 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068555 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468556 };
8557
8558 StaticSocketDataProvider ssl_bad_certificate(
8559 bad_cert_reads, arraysize(bad_cert_reads),
8560 bad_cert_writes, arraysize(bad_cert_writes));
8561 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8562 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068563 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8564 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468565
8566 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078567 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8568 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468570
8571 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078572 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8573 session_deps_.socket_factory->AddSocketDataProvider(&data);
8574 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468575
[email protected]49639fa2011-12-20 23:22:418576 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468577
danakj1fd259a02016-04-16 03:17:098578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168579 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468580
tfarina42834112016-09-22 13:38:208581 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468583
8584 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018585 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468586
bnc691fda62016-08-12 00:43:168587 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018588 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468589
8590 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018591 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468592
bnc691fda62016-08-12 00:43:168593 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468594
wezca1070932016-05-26 20:30:528595 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468596 EXPECT_EQ(100, response->headers->GetContentLength());
8597}
8598
bncd16676a2016-07-20 16:23:018599TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428600 HttpRequestInfo request;
8601 request.method = "GET";
bncce36dca22015-04-21 22:11:238602 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438603 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8604 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428605
danakj1fd259a02016-04-16 03:17:098606 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168607 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278608
[email protected]1c773ea12009-04-28 19:58:428609 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238610 MockWrite(
8611 "GET / HTTP/1.1\r\n"
8612 "Host: www.example.org\r\n"
8613 "Connection: keep-alive\r\n"
8614 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428615 };
8616
8617 // Lastly, the server responds with the actual content.
8618 MockRead data_reads[] = {
8619 MockRead("HTTP/1.0 200 OK\r\n"),
8620 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8621 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068622 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428623 };
8624
[email protected]31a2bfe2010-02-09 08:03:398625 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8626 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078627 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428628
[email protected]49639fa2011-12-20 23:22:418629 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428630
tfarina42834112016-09-22 13:38:208631 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428633
8634 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018635 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428636}
8637
bncd16676a2016-07-20 16:23:018638TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298639 HttpRequestInfo request;
8640 request.method = "GET";
bncce36dca22015-04-21 22:11:238641 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298642 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8643 "Chromium Ultra Awesome X Edition");
8644
rdsmith82957ad2015-09-16 19:42:038645 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278648
[email protected]da81f132010-08-18 23:39:298649 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178650 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8651 "Host: www.example.org:443\r\n"
8652 "Proxy-Connection: keep-alive\r\n"
8653 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298654 };
8655 MockRead data_reads[] = {
8656 // Return an error, so the transaction stops here (this test isn't
8657 // interested in the rest).
8658 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8659 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8660 MockRead("Proxy-Connection: close\r\n\r\n"),
8661 };
8662
8663 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8664 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078665 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298666
[email protected]49639fa2011-12-20 23:22:418667 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298668
tfarina42834112016-09-22 13:38:208669 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298671
8672 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018673 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298674}
8675
bncd16676a2016-07-20 16:23:018676TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428677 HttpRequestInfo request;
8678 request.method = "GET";
bncce36dca22015-04-21 22:11:238679 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168680 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8681 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428682
danakj1fd259a02016-04-16 03:17:098683 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278685
[email protected]1c773ea12009-04-28 19:58:428686 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238687 MockWrite(
8688 "GET / HTTP/1.1\r\n"
8689 "Host: www.example.org\r\n"
8690 "Connection: keep-alive\r\n"
8691 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428692 };
8693
8694 // Lastly, the server responds with the actual content.
8695 MockRead data_reads[] = {
8696 MockRead("HTTP/1.0 200 OK\r\n"),
8697 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8698 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068699 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428700 };
8701
[email protected]31a2bfe2010-02-09 08:03:398702 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8703 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078704 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428705
[email protected]49639fa2011-12-20 23:22:418706 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428707
tfarina42834112016-09-22 13:38:208708 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428710
8711 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018712 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428713}
8714
bncd16676a2016-07-20 16:23:018715TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428716 HttpRequestInfo request;
8717 request.method = "POST";
bncce36dca22015-04-21 22:11:238718 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428719
danakj1fd259a02016-04-16 03:17:098720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278722
[email protected]1c773ea12009-04-28 19:58:428723 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238724 MockWrite(
8725 "POST / HTTP/1.1\r\n"
8726 "Host: www.example.org\r\n"
8727 "Connection: keep-alive\r\n"
8728 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428729 };
8730
8731 // Lastly, the server responds with the actual content.
8732 MockRead data_reads[] = {
8733 MockRead("HTTP/1.0 200 OK\r\n"),
8734 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8735 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068736 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428737 };
8738
[email protected]31a2bfe2010-02-09 08:03:398739 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8740 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078741 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428742
[email protected]49639fa2011-12-20 23:22:418743 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428744
tfarina42834112016-09-22 13:38:208745 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428747
8748 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018749 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428750}
8751
bncd16676a2016-07-20 16:23:018752TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428753 HttpRequestInfo request;
8754 request.method = "PUT";
bncce36dca22015-04-21 22:11:238755 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428756
danakj1fd259a02016-04-16 03:17:098757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278759
[email protected]1c773ea12009-04-28 19:58:428760 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238761 MockWrite(
8762 "PUT / HTTP/1.1\r\n"
8763 "Host: www.example.org\r\n"
8764 "Connection: keep-alive\r\n"
8765 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428766 };
8767
8768 // Lastly, the server responds with the actual content.
8769 MockRead data_reads[] = {
8770 MockRead("HTTP/1.0 200 OK\r\n"),
8771 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8772 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068773 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428774 };
8775
[email protected]31a2bfe2010-02-09 08:03:398776 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8777 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078778 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428779
[email protected]49639fa2011-12-20 23:22:418780 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428781
tfarina42834112016-09-22 13:38:208782 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428784
8785 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018786 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428787}
8788
bncd16676a2016-07-20 16:23:018789TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428790 HttpRequestInfo request;
8791 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238792 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428793
danakj1fd259a02016-04-16 03:17:098794 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168795 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278796
[email protected]1c773ea12009-04-28 19:58:428797 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138798 MockWrite("HEAD / HTTP/1.1\r\n"
8799 "Host: www.example.org\r\n"
8800 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428801 };
8802
8803 // Lastly, the server responds with the actual content.
8804 MockRead data_reads[] = {
8805 MockRead("HTTP/1.0 200 OK\r\n"),
8806 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8807 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068808 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428809 };
8810
[email protected]31a2bfe2010-02-09 08:03:398811 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8812 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078813 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428814
[email protected]49639fa2011-12-20 23:22:418815 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428816
tfarina42834112016-09-22 13:38:208817 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428819
8820 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018821 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428822}
8823
bncd16676a2016-07-20 16:23:018824TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428825 HttpRequestInfo request;
8826 request.method = "GET";
bncce36dca22015-04-21 22:11:238827 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428828 request.load_flags = LOAD_BYPASS_CACHE;
8829
danakj1fd259a02016-04-16 03:17:098830 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278832
[email protected]1c773ea12009-04-28 19:58:428833 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238834 MockWrite(
8835 "GET / HTTP/1.1\r\n"
8836 "Host: www.example.org\r\n"
8837 "Connection: keep-alive\r\n"
8838 "Pragma: no-cache\r\n"
8839 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428840 };
8841
8842 // Lastly, the server responds with the actual content.
8843 MockRead data_reads[] = {
8844 MockRead("HTTP/1.0 200 OK\r\n"),
8845 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8846 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068847 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428848 };
8849
[email protected]31a2bfe2010-02-09 08:03:398850 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8851 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078852 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428853
[email protected]49639fa2011-12-20 23:22:418854 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428855
tfarina42834112016-09-22 13:38:208856 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428858
8859 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018860 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428861}
8862
bncd16676a2016-07-20 16:23:018863TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428864 HttpRequestInfo request;
8865 request.method = "GET";
bncce36dca22015-04-21 22:11:238866 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428867 request.load_flags = LOAD_VALIDATE_CACHE;
8868
danakj1fd259a02016-04-16 03:17:098869 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278871
[email protected]1c773ea12009-04-28 19:58:428872 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238873 MockWrite(
8874 "GET / HTTP/1.1\r\n"
8875 "Host: www.example.org\r\n"
8876 "Connection: keep-alive\r\n"
8877 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428878 };
8879
8880 // Lastly, the server responds with the actual content.
8881 MockRead data_reads[] = {
8882 MockRead("HTTP/1.0 200 OK\r\n"),
8883 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8884 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068885 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428886 };
8887
[email protected]31a2bfe2010-02-09 08:03:398888 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8889 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078890 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428891
[email protected]49639fa2011-12-20 23:22:418892 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428893
tfarina42834112016-09-22 13:38:208894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428896
8897 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018898 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428899}
8900
bncd16676a2016-07-20 16:23:018901TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428902 HttpRequestInfo request;
8903 request.method = "GET";
bncce36dca22015-04-21 22:11:238904 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438905 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428906
danakj1fd259a02016-04-16 03:17:098907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168908 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278909
[email protected]1c773ea12009-04-28 19:58:428910 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238911 MockWrite(
8912 "GET / HTTP/1.1\r\n"
8913 "Host: www.example.org\r\n"
8914 "Connection: keep-alive\r\n"
8915 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428916 };
8917
8918 // Lastly, the server responds with the actual content.
8919 MockRead data_reads[] = {
8920 MockRead("HTTP/1.0 200 OK\r\n"),
8921 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8922 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068923 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428924 };
8925
[email protected]31a2bfe2010-02-09 08:03:398926 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8927 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078928 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428929
[email protected]49639fa2011-12-20 23:22:418930 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428931
tfarina42834112016-09-22 13:38:208932 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428934
8935 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018936 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428937}
8938
bncd16676a2016-07-20 16:23:018939TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478940 HttpRequestInfo request;
8941 request.method = "GET";
bncce36dca22015-04-21 22:11:238942 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438943 request.extra_headers.SetHeader("referer", "www.foo.com");
8944 request.extra_headers.SetHeader("hEllo", "Kitty");
8945 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478946
danakj1fd259a02016-04-16 03:17:098947 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278949
[email protected]270c6412010-03-29 22:02:478950 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238951 MockWrite(
8952 "GET / HTTP/1.1\r\n"
8953 "Host: www.example.org\r\n"
8954 "Connection: keep-alive\r\n"
8955 "referer: www.foo.com\r\n"
8956 "hEllo: Kitty\r\n"
8957 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478958 };
8959
8960 // Lastly, the server responds with the actual content.
8961 MockRead data_reads[] = {
8962 MockRead("HTTP/1.0 200 OK\r\n"),
8963 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8964 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068965 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478966 };
8967
8968 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8969 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078970 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478971
[email protected]49639fa2011-12-20 23:22:418972 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478973
tfarina42834112016-09-22 13:38:208974 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018975 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478976
8977 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018978 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478979}
8980
bncd16676a2016-07-20 16:23:018981TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278982 HttpRequestInfo request;
8983 request.method = "GET";
bncce36dca22015-04-21 22:11:238984 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278985
rdsmith82957ad2015-09-16 19:42:038986 session_deps_.proxy_service =
8987 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518988 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078989 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028990
danakj1fd259a02016-04-16 03:17:098991 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028993
[email protected]3cd17242009-06-23 02:59:028994 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8995 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8996
8997 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238998 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8999 MockWrite(
9000 "GET / HTTP/1.1\r\n"
9001 "Host: www.example.org\r\n"
9002 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029003
9004 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069005 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029006 MockRead("HTTP/1.0 200 OK\r\n"),
9007 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9008 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069009 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029010 };
9011
[email protected]31a2bfe2010-02-09 08:03:399012 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9013 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079014 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029015
[email protected]49639fa2011-12-20 23:22:419016 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029017
tfarina42834112016-09-22 13:38:209018 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029020
9021 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019022 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029023
bnc691fda62016-08-12 00:43:169024 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529025 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029026
tbansal2ecbbc72016-10-06 17:15:479027 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209028 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169029 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209030 TestLoadTimingNotReusedWithPac(load_timing_info,
9031 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9032
[email protected]3cd17242009-06-23 02:59:029033 std::string response_text;
bnc691fda62016-08-12 00:43:169034 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019035 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029036 EXPECT_EQ("Payload", response_text);
9037}
9038
bncd16676a2016-07-20 16:23:019039TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279040 HttpRequestInfo request;
9041 request.method = "GET";
bncce36dca22015-04-21 22:11:239042 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279043
rdsmith82957ad2015-09-16 19:42:039044 session_deps_.proxy_service =
9045 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519046 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079047 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029048
danakj1fd259a02016-04-16 03:17:099049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169050 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029051
[email protected]3cd17242009-06-23 02:59:029052 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9053 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9054
9055 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239056 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9057 arraysize(write_buffer)),
9058 MockWrite(
9059 "GET / HTTP/1.1\r\n"
9060 "Host: www.example.org\r\n"
9061 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029062
9063 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019064 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9065 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359066 MockRead("HTTP/1.0 200 OK\r\n"),
9067 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9068 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069069 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359070 };
9071
[email protected]31a2bfe2010-02-09 08:03:399072 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9073 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079074 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359075
[email protected]8ddf8322012-02-23 18:08:069076 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079077 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359078
[email protected]49639fa2011-12-20 23:22:419079 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359080
tfarina42834112016-09-22 13:38:209081 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019082 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359083
9084 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019085 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359086
[email protected]029c83b62013-01-24 05:28:209087 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169088 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209089 TestLoadTimingNotReusedWithPac(load_timing_info,
9090 CONNECT_TIMING_HAS_SSL_TIMES);
9091
bnc691fda62016-08-12 00:43:169092 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529093 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479094 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359095
9096 std::string response_text;
bnc691fda62016-08-12 00:43:169097 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019098 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359099 EXPECT_EQ("Payload", response_text);
9100}
9101
bncd16676a2016-07-20 16:23:019102TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209103 HttpRequestInfo request;
9104 request.method = "GET";
bncce36dca22015-04-21 22:11:239105 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209106
rdsmith82957ad2015-09-16 19:42:039107 session_deps_.proxy_service =
9108 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519109 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079110 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209111
danakj1fd259a02016-04-16 03:17:099112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169113 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209114
9115 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9116 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9117
9118 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239119 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9120 MockWrite(
9121 "GET / HTTP/1.1\r\n"
9122 "Host: www.example.org\r\n"
9123 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209124
9125 MockRead data_reads[] = {
9126 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9127 MockRead("HTTP/1.0 200 OK\r\n"),
9128 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9129 MockRead("Payload"),
9130 MockRead(SYNCHRONOUS, OK)
9131 };
9132
9133 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9134 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079135 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209136
9137 TestCompletionCallback callback;
9138
tfarina42834112016-09-22 13:38:209139 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209141
9142 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019143 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209144
bnc691fda62016-08-12 00:43:169145 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529146 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209147
9148 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169149 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209150 TestLoadTimingNotReused(load_timing_info,
9151 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9152
9153 std::string response_text;
bnc691fda62016-08-12 00:43:169154 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019155 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209156 EXPECT_EQ("Payload", response_text);
9157}
9158
bncd16676a2016-07-20 16:23:019159TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279160 HttpRequestInfo request;
9161 request.method = "GET";
bncce36dca22015-04-21 22:11:239162 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279163
rdsmith82957ad2015-09-16 19:42:039164 session_deps_.proxy_service =
9165 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519166 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079167 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359168
danakj1fd259a02016-04-16 03:17:099169 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169170 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359171
[email protected]e0c27be2009-07-15 13:09:359172 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9173 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379174 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239175 0x05, // Version
9176 0x01, // Command (CONNECT)
9177 0x00, // Reserved.
9178 0x03, // Address type (DOMAINNAME).
9179 0x0F, // Length of domain (15)
9180 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9181 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379182 };
[email protected]e0c27be2009-07-15 13:09:359183 const char kSOCKS5OkResponse[] =
9184 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9185
9186 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239187 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9188 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9189 MockWrite(
9190 "GET / HTTP/1.1\r\n"
9191 "Host: www.example.org\r\n"
9192 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359193
9194 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019195 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9196 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359197 MockRead("HTTP/1.0 200 OK\r\n"),
9198 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9199 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069200 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359201 };
9202
[email protected]31a2bfe2010-02-09 08:03:399203 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9204 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079205 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359206
[email protected]49639fa2011-12-20 23:22:419207 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359208
tfarina42834112016-09-22 13:38:209209 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359211
9212 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019213 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359214
bnc691fda62016-08-12 00:43:169215 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529216 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479217 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359218
[email protected]029c83b62013-01-24 05:28:209219 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169220 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209221 TestLoadTimingNotReusedWithPac(load_timing_info,
9222 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9223
[email protected]e0c27be2009-07-15 13:09:359224 std::string response_text;
bnc691fda62016-08-12 00:43:169225 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019226 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359227 EXPECT_EQ("Payload", response_text);
9228}
9229
bncd16676a2016-07-20 16:23:019230TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279231 HttpRequestInfo request;
9232 request.method = "GET";
bncce36dca22015-04-21 22:11:239233 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279234
rdsmith82957ad2015-09-16 19:42:039235 session_deps_.proxy_service =
9236 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519237 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079238 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359239
danakj1fd259a02016-04-16 03:17:099240 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359242
[email protected]e0c27be2009-07-15 13:09:359243 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9244 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379245 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239246 0x05, // Version
9247 0x01, // Command (CONNECT)
9248 0x00, // Reserved.
9249 0x03, // Address type (DOMAINNAME).
9250 0x0F, // Length of domain (15)
9251 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9252 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379253 };
9254
[email protected]e0c27be2009-07-15 13:09:359255 const char kSOCKS5OkResponse[] =
9256 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9257
9258 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239259 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9260 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9261 arraysize(kSOCKS5OkRequest)),
9262 MockWrite(
9263 "GET / HTTP/1.1\r\n"
9264 "Host: www.example.org\r\n"
9265 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359266
9267 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019268 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9269 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029270 MockRead("HTTP/1.0 200 OK\r\n"),
9271 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9272 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069273 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029274 };
9275
[email protected]31a2bfe2010-02-09 08:03:399276 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9277 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079278 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029279
[email protected]8ddf8322012-02-23 18:08:069280 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029282
[email protected]49639fa2011-12-20 23:22:419283 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029284
tfarina42834112016-09-22 13:38:209285 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019286 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029287
9288 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019289 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029290
bnc691fda62016-08-12 00:43:169291 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529292 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479293 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029294
[email protected]029c83b62013-01-24 05:28:209295 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169296 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209297 TestLoadTimingNotReusedWithPac(load_timing_info,
9298 CONNECT_TIMING_HAS_SSL_TIMES);
9299
[email protected]3cd17242009-06-23 02:59:029300 std::string response_text;
bnc691fda62016-08-12 00:43:169301 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019302 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029303 EXPECT_EQ("Payload", response_text);
9304}
9305
[email protected]448d4ca52012-03-04 04:12:239306namespace {
9307
[email protected]04e5be32009-06-26 20:00:319308// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069309
9310struct GroupNameTest {
9311 std::string proxy_server;
9312 std::string url;
9313 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189314 bool ssl;
[email protected]2d731a32010-04-29 01:04:069315};
9316
danakj1fd259a02016-04-16 03:17:099317std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079318 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099319 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069320
bnc525e175a2016-06-20 12:36:409321 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539322 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219323 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129324 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219325 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429326 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469327 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069328
9329 return session;
9330}
9331
mmenkee65e7af2015-10-13 17:16:429332int GroupNameTransactionHelper(const std::string& url,
9333 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069334 HttpRequestInfo request;
9335 request.method = "GET";
9336 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069337
bnc691fda62016-08-12 00:43:169338 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279339
[email protected]49639fa2011-12-20 23:22:419340 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069341
9342 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209343 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069344}
9345
[email protected]448d4ca52012-03-04 04:12:239346} // namespace
9347
bncd16676a2016-07-20 16:23:019348TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069349 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239350 {
9351 "", // unused
9352 "http://www.example.org/direct",
9353 "www.example.org:80",
9354 false,
9355 },
9356 {
9357 "", // unused
9358 "http://[2001:1418:13:1::25]/direct",
9359 "[2001:1418:13:1::25]:80",
9360 false,
9361 },
[email protected]04e5be32009-06-26 20:00:319362
bncce36dca22015-04-21 22:11:239363 // SSL Tests
9364 {
9365 "", // unused
9366 "https://www.example.org/direct_ssl",
9367 "ssl/www.example.org:443",
9368 true,
9369 },
9370 {
9371 "", // unused
9372 "https://[2001:1418:13:1::25]/direct",
9373 "ssl/[2001:1418:13:1::25]:443",
9374 true,
9375 },
9376 {
9377 "", // unused
bncaa60ff402016-06-22 19:12:429378 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239379 "ssl/host.with.alternate:443",
9380 true,
9381 },
[email protected]2d731a32010-04-29 01:04:069382 };
[email protected]2ff8b312010-04-26 22:20:549383
viettrungluue4a8b882014-10-16 06:17:389384 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039385 session_deps_.proxy_service =
9386 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099387 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409388 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069389
mmenkee65e7af2015-10-13 17:16:429390 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289391 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589392 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139393 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589394 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
9395 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029396 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9397 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489398 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069399
9400 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429401 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189402 if (tests[i].ssl)
9403 EXPECT_EQ(tests[i].expected_group_name,
9404 ssl_conn_pool->last_group_name_received());
9405 else
9406 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289407 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069408 }
[email protected]2d731a32010-04-29 01:04:069409}
9410
bncd16676a2016-07-20 16:23:019411TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069412 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239413 {
9414 "http_proxy",
9415 "http://www.example.org/http_proxy_normal",
9416 "www.example.org:80",
9417 false,
9418 },
[email protected]2d731a32010-04-29 01:04:069419
bncce36dca22015-04-21 22:11:239420 // SSL Tests
9421 {
9422 "http_proxy",
9423 "https://www.example.org/http_connect_ssl",
9424 "ssl/www.example.org:443",
9425 true,
9426 },
[email protected]af3490e2010-10-16 21:02:299427
bncce36dca22015-04-21 22:11:239428 {
9429 "http_proxy",
bncaa60ff402016-06-22 19:12:429430 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239431 "ssl/host.with.alternate:443",
9432 true,
9433 },
[email protected]45499252013-01-23 17:12:569434
bncce36dca22015-04-21 22:11:239435 {
9436 "http_proxy",
9437 "ftp://ftp.google.com/http_proxy_normal",
9438 "ftp/ftp.google.com:21",
9439 false,
9440 },
[email protected]2d731a32010-04-29 01:04:069441 };
9442
viettrungluue4a8b882014-10-16 06:17:389443 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039444 session_deps_.proxy_service =
9445 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099446 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409447 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069448
mmenkee65e7af2015-10-13 17:16:429449 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069450
[email protected]e60e47a2010-07-14 03:37:189451 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139452 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349453 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139454 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349455 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589456 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399457 mock_pool_manager->SetSocketPoolForHTTPProxy(
9458 proxy_host, base::WrapUnique(http_proxy_pool));
9459 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9460 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489461 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069462
9463 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429464 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189465 if (tests[i].ssl)
9466 EXPECT_EQ(tests[i].expected_group_name,
9467 ssl_conn_pool->last_group_name_received());
9468 else
9469 EXPECT_EQ(tests[i].expected_group_name,
9470 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069471 }
[email protected]2d731a32010-04-29 01:04:069472}
9473
bncd16676a2016-07-20 16:23:019474TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069475 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239476 {
9477 "socks4://socks_proxy:1080",
9478 "http://www.example.org/socks4_direct",
9479 "socks4/www.example.org:80",
9480 false,
9481 },
9482 {
9483 "socks5://socks_proxy:1080",
9484 "http://www.example.org/socks5_direct",
9485 "socks5/www.example.org:80",
9486 false,
9487 },
[email protected]2d731a32010-04-29 01:04:069488
bncce36dca22015-04-21 22:11:239489 // SSL Tests
9490 {
9491 "socks4://socks_proxy:1080",
9492 "https://www.example.org/socks4_ssl",
9493 "socks4/ssl/www.example.org:443",
9494 true,
9495 },
9496 {
9497 "socks5://socks_proxy:1080",
9498 "https://www.example.org/socks5_ssl",
9499 "socks5/ssl/www.example.org:443",
9500 true,
9501 },
[email protected]af3490e2010-10-16 21:02:299502
bncce36dca22015-04-21 22:11:239503 {
9504 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429505 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239506 "socks4/ssl/host.with.alternate:443",
9507 true,
9508 },
[email protected]04e5be32009-06-26 20:00:319509 };
9510
viettrungluue4a8b882014-10-16 06:17:389511 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039512 session_deps_.proxy_service =
9513 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099514 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409515 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029516
mmenkee65e7af2015-10-13 17:16:429517 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319518
[email protected]e60e47a2010-07-14 03:37:189519 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139520 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349521 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139522 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349523 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589524 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399525 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9526 proxy_host, base::WrapUnique(socks_conn_pool));
9527 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9528 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489529 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319530
bnc691fda62016-08-12 00:43:169531 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319532
[email protected]2d731a32010-04-29 01:04:069533 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429534 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189535 if (tests[i].ssl)
9536 EXPECT_EQ(tests[i].expected_group_name,
9537 ssl_conn_pool->last_group_name_received());
9538 else
9539 EXPECT_EQ(tests[i].expected_group_name,
9540 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319541 }
9542}
9543
bncd16676a2016-07-20 16:23:019544TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279545 HttpRequestInfo request;
9546 request.method = "GET";
bncce36dca22015-04-21 22:11:239547 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279548
rdsmith82957ad2015-09-16 19:42:039549 session_deps_.proxy_service =
9550 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329551
[email protected]69719062010-01-05 20:09:219552 // This simulates failure resolving all hostnames; that means we will fail
9553 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079554 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329555
danakj1fd259a02016-04-16 03:17:099556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169557 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259558
[email protected]49639fa2011-12-20 23:22:419559 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259560
tfarina42834112016-09-22 13:38:209561 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019562 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259563
[email protected]9172a982009-06-06 00:30:259564 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019565 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259566}
9567
[email protected]685af592010-05-11 19:31:249568// Base test to make sure that when the load flags for a request specify to
9569// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029570void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079571 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279572 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109573 HttpRequestInfo request_info;
9574 request_info.method = "GET";
9575 request_info.load_flags = load_flags;
9576 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279577
[email protected]a2c2fb92009-07-18 07:31:049578 // Select a host resolver that does caching.
bnc87dcefc2017-05-25 12:47:589579 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329580
danakj1fd259a02016-04-16 03:17:099581 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289583
bncce36dca22015-04-21 22:11:239584 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289585 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299586 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109587 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079588 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239589 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109590 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209591 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479593 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019594 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289595
9596 // Verify that it was added to host cache, by doing a subsequent async lookup
9597 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109598 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079599 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239600 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109601 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209602 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019603 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289604
bncce36dca22015-04-21 22:11:239605 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289606 // we can tell if the next lookup hit the cache, or the "network".
9607 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239608 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289609
9610 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9611 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069612 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399613 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079614 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289615
[email protected]3b9cca42009-06-16 01:08:289616 // Run the request.
tfarina42834112016-09-22 13:38:209617 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019618 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419619 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289620
9621 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239622 // "www.example.org".
robpercival214763f2016-07-01 23:27:019623 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289624}
9625
[email protected]685af592010-05-11 19:31:249626// There are multiple load flags that should trigger the host cache bypass.
9627// Test each in isolation:
bncd16676a2016-07-20 16:23:019628TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249629 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9630}
9631
bncd16676a2016-07-20 16:23:019632TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249633 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9634}
9635
bncd16676a2016-07-20 16:23:019636TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249637 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9638}
9639
[email protected]0877e3d2009-10-17 22:29:579640// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019641TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579642 HttpRequestInfo request;
9643 request.method = "GET";
9644 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579645
9646 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069647 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579648 };
[email protected]31a2bfe2010-02-09 08:03:399649 StaticSocketDataProvider data(NULL, 0,
9650 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079651 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099652 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579653
[email protected]49639fa2011-12-20 23:22:419654 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579655
bnc691fda62016-08-12 00:43:169656 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579657
tfarina42834112016-09-22 13:38:209658 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579660
9661 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019662 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599663
9664 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169665 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599666 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579667}
9668
zmo9528c9f42015-08-04 22:12:089669// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019670TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579671 HttpRequestInfo request;
9672 request.method = "GET";
9673 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579674
9675 MockRead data_reads[] = {
9676 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069677 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579678 };
9679
[email protected]31a2bfe2010-02-09 08:03:399680 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079681 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099682 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579683
[email protected]49639fa2011-12-20 23:22:419684 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579685
bnc691fda62016-08-12 00:43:169686 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579687
tfarina42834112016-09-22 13:38:209688 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579690
9691 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019692 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089693
bnc691fda62016-08-12 00:43:169694 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529695 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089696
wezca1070932016-05-26 20:30:529697 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089698 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9699
9700 std::string response_data;
bnc691fda62016-08-12 00:43:169701 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019702 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089703 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599704
9705 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169706 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599707 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579708}
9709
9710// Make sure that a dropped connection while draining the body for auth
9711// restart does the right thing.
bncd16676a2016-07-20 16:23:019712TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579713 HttpRequestInfo request;
9714 request.method = "GET";
bncce36dca22015-04-21 22:11:239715 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579716
9717 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239718 MockWrite(
9719 "GET / HTTP/1.1\r\n"
9720 "Host: www.example.org\r\n"
9721 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579722 };
9723
9724 MockRead data_reads1[] = {
9725 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9726 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9727 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9728 MockRead("Content-Length: 14\r\n\r\n"),
9729 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069730 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579731 };
9732
[email protected]31a2bfe2010-02-09 08:03:399733 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9734 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079735 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579736
bnc691fda62016-08-12 00:43:169737 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579738 // be issuing -- the final header line contains the credentials.
9739 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239740 MockWrite(
9741 "GET / HTTP/1.1\r\n"
9742 "Host: www.example.org\r\n"
9743 "Connection: keep-alive\r\n"
9744 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579745 };
9746
9747 // Lastly, the server responds with the actual content.
9748 MockRead data_reads2[] = {
9749 MockRead("HTTP/1.1 200 OK\r\n"),
9750 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9751 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069752 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579753 };
9754
[email protected]31a2bfe2010-02-09 08:03:399755 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9756 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079757 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579759
[email protected]49639fa2011-12-20 23:22:419760 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579761
bnc691fda62016-08-12 00:43:169762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509763
tfarina42834112016-09-22 13:38:209764 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019765 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579766
9767 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019768 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579769
bnc691fda62016-08-12 00:43:169770 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529771 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049772 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579773
[email protected]49639fa2011-12-20 23:22:419774 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579775
bnc691fda62016-08-12 00:43:169776 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579778
9779 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019780 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579781
bnc691fda62016-08-12 00:43:169782 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529783 ASSERT_TRUE(response);
9784 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579785 EXPECT_EQ(100, response->headers->GetContentLength());
9786}
9787
9788// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019789TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039790 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579791
9792 HttpRequestInfo request;
9793 request.method = "GET";
bncce36dca22015-04-21 22:11:239794 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579795
9796 MockRead proxy_reads[] = {
9797 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069798 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579799 };
9800
[email protected]31a2bfe2010-02-09 08:03:399801 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069802 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579803
[email protected]bb88e1d32013-05-03 23:11:079804 session_deps_.socket_factory->AddSocketDataProvider(&data);
9805 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579806
[email protected]49639fa2011-12-20 23:22:419807 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579808
[email protected]bb88e1d32013-05-03 23:11:079809 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579810
danakj1fd259a02016-04-16 03:17:099811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579813
tfarina42834112016-09-22 13:38:209814 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579816
9817 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019818 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579819}
9820
bncd16676a2016-07-20 16:23:019821TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469822 HttpRequestInfo request;
9823 request.method = "GET";
bncce36dca22015-04-21 22:11:239824 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469825
danakj1fd259a02016-04-16 03:17:099826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279828
[email protected]e22e1362009-11-23 21:31:129829 MockRead data_reads[] = {
9830 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069831 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129832 };
[email protected]9492e4a2010-02-24 00:58:469833
9834 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079835 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469836
[email protected]49639fa2011-12-20 23:22:419837 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469838
tfarina42834112016-09-22 13:38:209839 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469841
robpercival214763f2016-07-01 23:27:019842 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469843
bnc691fda62016-08-12 00:43:169844 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529845 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469846
wezca1070932016-05-26 20:30:529847 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469848 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9849
9850 std::string response_data;
bnc691fda62016-08-12 00:43:169851 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019852 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129853}
9854
bncd16676a2016-07-20 16:23:019855TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159856 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529857 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149858 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219859 UploadFileElementReader::ScopedOverridingContentLengthForTests
9860 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339861
danakj1fd259a02016-04-16 03:17:099862 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079863 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149864 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079865 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229866 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279867
9868 HttpRequestInfo request;
9869 request.method = "POST";
bncce36dca22015-04-21 22:11:239870 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279871 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279872
danakj1fd259a02016-04-16 03:17:099873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339875
9876 MockRead data_reads[] = {
9877 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9878 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069879 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339880 };
[email protected]31a2bfe2010-02-09 08:03:399881 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079882 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339883
[email protected]49639fa2011-12-20 23:22:419884 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339885
tfarina42834112016-09-22 13:38:209886 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339888
9889 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019890 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339891
bnc691fda62016-08-12 00:43:169892 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529893 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339894
maksim.sisove869bf52016-06-23 17:11:529895 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339896
[email protected]dd3aa792013-07-16 19:10:239897 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339898}
9899
bncd16676a2016-07-20 16:23:019900TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159901 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529902 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369903 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:489904 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
9905 base::WriteFile(temp_file, temp_file_content.c_str(),
9906 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119907 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369908
danakj1fd259a02016-04-16 03:17:099909 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079910 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149911 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079912 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229913 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279914
9915 HttpRequestInfo request;
9916 request.method = "POST";
bncce36dca22015-04-21 22:11:239917 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279918 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279919
[email protected]999dd8c2013-11-12 06:45:549920 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369923
[email protected]999dd8c2013-11-12 06:45:549924 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079925 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369926
[email protected]49639fa2011-12-20 23:22:419927 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369928
tfarina42834112016-09-22 13:38:209929 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369931
9932 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019933 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369934
[email protected]dd3aa792013-07-16 19:10:239935 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369936}
9937
bncd16676a2016-07-20 16:23:019938TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039939 class FakeUploadElementReader : public UploadElementReader {
9940 public:
9941 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209942 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039943
9944 const CompletionCallback& callback() const { return callback_; }
9945
9946 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209947 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039948 callback_ = callback;
9949 return ERR_IO_PENDING;
9950 }
avibf0746c2015-12-09 19:53:149951 uint64_t GetContentLength() const override { return 0; }
9952 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209953 int Read(IOBuffer* buf,
9954 int buf_length,
9955 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039956 return ERR_FAILED;
9957 }
9958
9959 private:
9960 CompletionCallback callback_;
9961 };
9962
9963 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099964 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9965 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229966 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039967
9968 HttpRequestInfo request;
9969 request.method = "POST";
bncce36dca22015-04-21 22:11:239970 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039971 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039972
danakj1fd259a02016-04-16 03:17:099973 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:589974 auto trans =
9975 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:039976
9977 StaticSocketDataProvider data;
9978 session_deps_.socket_factory->AddSocketDataProvider(&data);
9979
9980 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209981 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559983 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039984
9985 // Transaction is pending on request body initialization.
9986 ASSERT_FALSE(fake_reader->callback().is_null());
9987
9988 // Return Init()'s result after the transaction gets destroyed.
9989 trans.reset();
9990 fake_reader->callback().Run(OK); // Should not crash.
9991}
9992
[email protected]aeefc9e82010-02-19 16:18:279993// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019994TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279995 HttpRequestInfo request;
9996 request.method = "GET";
bncce36dca22015-04-21 22:11:239997 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279998
9999 // First transaction will request a resource and receive a Basic challenge
10000 // with realm="first_realm".
10001 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310002 MockWrite(
10003 "GET / HTTP/1.1\r\n"
10004 "Host: www.example.org\r\n"
10005 "Connection: keep-alive\r\n"
10006 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710007 };
10008 MockRead data_reads1[] = {
10009 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10010 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10011 "\r\n"),
10012 };
10013
bnc691fda62016-08-12 00:43:1610014 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710015 // for first_realm. The server will reject and provide a challenge with
10016 // second_realm.
10017 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310018 MockWrite(
10019 "GET / HTTP/1.1\r\n"
10020 "Host: www.example.org\r\n"
10021 "Connection: keep-alive\r\n"
10022 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10023 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710024 };
10025 MockRead data_reads2[] = {
10026 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10027 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10028 "\r\n"),
10029 };
10030
10031 // This again fails, and goes back to first_realm. Make sure that the
10032 // entry is removed from cache.
10033 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310034 MockWrite(
10035 "GET / HTTP/1.1\r\n"
10036 "Host: www.example.org\r\n"
10037 "Connection: keep-alive\r\n"
10038 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10039 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710040 };
10041 MockRead data_reads3[] = {
10042 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10043 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10044 "\r\n"),
10045 };
10046
10047 // Try one last time (with the correct password) and get the resource.
10048 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310049 MockWrite(
10050 "GET / HTTP/1.1\r\n"
10051 "Host: www.example.org\r\n"
10052 "Connection: keep-alive\r\n"
10053 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10054 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710055 };
10056 MockRead data_reads4[] = {
10057 MockRead("HTTP/1.1 200 OK\r\n"
10058 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010059 "Content-Length: 5\r\n"
10060 "\r\n"
10061 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710062 };
10063
10064 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10065 data_writes1, arraysize(data_writes1));
10066 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10067 data_writes2, arraysize(data_writes2));
10068 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10069 data_writes3, arraysize(data_writes3));
10070 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10071 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710072 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10073 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10074 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10075 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710076
[email protected]49639fa2011-12-20 23:22:4110077 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710078
danakj1fd259a02016-04-16 03:17:0910079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610080 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010081
[email protected]aeefc9e82010-02-19 16:18:2710082 // Issue the first request with Authorize headers. There should be a
10083 // password prompt for first_realm waiting to be filled in after the
10084 // transaction completes.
tfarina42834112016-09-22 13:38:2010085 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710087 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110088 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610089 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210090 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410091 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210092 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410093 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310094 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410095 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910096 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710097
10098 // Issue the second request with an incorrect password. There should be a
10099 // password prompt for second_realm waiting to be filled in after the
10100 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110101 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610102 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10103 callback2.callback());
robpercival214763f2016-07-01 23:27:0110104 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710105 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110106 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610107 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210108 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410109 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210110 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410111 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310112 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410113 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910114 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710115
10116 // Issue the third request with another incorrect password. There should be
10117 // a password prompt for first_realm waiting to be filled in. If the password
10118 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10119 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110120 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610121 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10122 callback3.callback());
robpercival214763f2016-07-01 23:27:0110123 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710124 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110125 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610126 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210127 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410128 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210129 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410130 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310131 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410132 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910133 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710134
10135 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110136 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610137 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10138 callback4.callback());
robpercival214763f2016-07-01 23:27:0110139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710140 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110141 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610142 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210143 ASSERT_TRUE(response);
10144 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710145}
10146
bncd16676a2016-07-20 16:23:0110147TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210148 MockRead data_reads[] = {
10149 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310150 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210151 MockRead("\r\n"),
10152 MockRead("hello world"),
10153 MockRead(SYNCHRONOUS, OK),
10154 };
10155
10156 HttpRequestInfo request;
10157 request.method = "GET";
bncb26024382016-06-29 02:39:4510158 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210159
10160 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210161 session_deps_.socket_factory->AddSocketDataProvider(&data);
10162
bncb26024382016-06-29 02:39:4510163 SSLSocketDataProvider ssl(ASYNC, OK);
10164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10165
bncc958faa2015-07-31 18:14:5210166 TestCompletionCallback callback;
10167
danakj1fd259a02016-04-16 03:17:0910168 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210170
tfarina42834112016-09-22 13:38:2010171 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210173
bncb26024382016-06-29 02:39:4510174 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010175 HttpServerProperties* http_server_properties =
10176 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410177 EXPECT_TRUE(
10178 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210179
robpercival214763f2016-07-01 23:27:0110180 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210181
bnc691fda62016-08-12 00:43:1610182 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210183 ASSERT_TRUE(response);
10184 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210185 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10186 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210187 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210188
10189 std::string response_data;
bnc691fda62016-08-12 00:43:1610190 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210191 EXPECT_EQ("hello world", response_data);
10192
zhongyic4de03032017-05-19 04:07:3410193 AlternativeServiceInfoVector alternative_service_info_vector =
10194 http_server_properties->GetAlternativeServiceInfos(test_server);
10195 ASSERT_EQ(1u, alternative_service_info_vector.size());
10196 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10197 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410198 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210199}
10200
bnce3dd56f2016-06-01 10:37:1110201// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110202TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110203 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110204 MockRead data_reads[] = {
10205 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310206 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110207 MockRead("\r\n"),
10208 MockRead("hello world"),
10209 MockRead(SYNCHRONOUS, OK),
10210 };
10211
10212 HttpRequestInfo request;
10213 request.method = "GET";
10214 request.url = GURL("http://www.example.org/");
10215 request.load_flags = 0;
10216
10217 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10218 session_deps_.socket_factory->AddSocketDataProvider(&data);
10219
10220 TestCompletionCallback callback;
10221
10222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110224
10225 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010226 HttpServerProperties* http_server_properties =
10227 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410228 EXPECT_TRUE(
10229 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110230
tfarina42834112016-09-22 13:38:2010231 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110232 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10233 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110234
bnc691fda62016-08-12 00:43:1610235 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110236 ASSERT_TRUE(response);
10237 ASSERT_TRUE(response->headers);
10238 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10239 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210240 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110241
10242 std::string response_data;
bnc691fda62016-08-12 00:43:1610243 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110244 EXPECT_EQ("hello world", response_data);
10245
zhongyic4de03032017-05-19 04:07:3410246 EXPECT_TRUE(
10247 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110248}
10249
bnca86731e2017-04-17 12:31:2810250// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510251// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110252TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510253 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810254 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510255
bnc8bef8da22016-05-30 01:28:2510256 HttpRequestInfo request;
10257 request.method = "GET";
bncb26024382016-06-29 02:39:4510258 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510259 request.load_flags = 0;
10260
10261 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10262 StaticSocketDataProvider first_data;
10263 first_data.set_connect_data(mock_connect);
10264 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510265 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610266 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510267 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510268
10269 MockRead data_reads[] = {
10270 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10271 MockRead(ASYNC, OK),
10272 };
10273 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10274 0);
10275 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10276
10277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10278
bnc525e175a2016-06-20 12:36:4010279 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510280 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110281 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10282 444);
bnc8bef8da22016-05-30 01:28:2510283 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110284 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510285 url::SchemeHostPort(request.url), alternative_service, expiration);
10286
bnc691fda62016-08-12 00:43:1610287 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510288 TestCompletionCallback callback;
10289
tfarina42834112016-09-22 13:38:2010290 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510291 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110292 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510293}
10294
bnce3dd56f2016-06-01 10:37:1110295// Regression test for https://crbug.com/615497:
10296// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110297TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110298 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110299 HttpRequestInfo request;
10300 request.method = "GET";
10301 request.url = GURL("http://www.example.org/");
10302 request.load_flags = 0;
10303
10304 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10305 StaticSocketDataProvider first_data;
10306 first_data.set_connect_data(mock_connect);
10307 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10308
10309 MockRead data_reads[] = {
10310 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10311 MockRead(ASYNC, OK),
10312 };
10313 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10314 0);
10315 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10316
10317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10318
bnc525e175a2016-06-20 12:36:4010319 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110320 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110321 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110322 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110323 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110324 url::SchemeHostPort(request.url), alternative_service, expiration);
10325
bnc691fda62016-08-12 00:43:1610326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110327 TestCompletionCallback callback;
10328
tfarina42834112016-09-22 13:38:2010329 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110330 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110331 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110332}
10333
bncd16676a2016-07-20 16:23:0110334TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810335 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910336 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010337 HttpServerProperties* http_server_properties =
10338 session->http_server_properties();
bncb26024382016-06-29 02:39:4510339 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110340 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810341 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110342 http_server_properties->SetQuicAlternativeService(
10343 test_server, alternative_service, expiration,
10344 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410345 EXPECT_EQ(
10346 1u,
10347 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810348
10349 // Send a clear header.
10350 MockRead data_reads[] = {
10351 MockRead("HTTP/1.1 200 OK\r\n"),
10352 MockRead("Alt-Svc: clear\r\n"),
10353 MockRead("\r\n"),
10354 MockRead("hello world"),
10355 MockRead(SYNCHRONOUS, OK),
10356 };
10357 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10358 session_deps_.socket_factory->AddSocketDataProvider(&data);
10359
bncb26024382016-06-29 02:39:4510360 SSLSocketDataProvider ssl(ASYNC, OK);
10361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10362
bnc4f575852015-10-14 18:35:0810363 HttpRequestInfo request;
10364 request.method = "GET";
bncb26024382016-06-29 02:39:4510365 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810366
10367 TestCompletionCallback callback;
10368
bnc691fda62016-08-12 00:43:1610369 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810370
tfarina42834112016-09-22 13:38:2010371 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110372 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810373
bnc691fda62016-08-12 00:43:1610374 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210375 ASSERT_TRUE(response);
10376 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810377 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10378 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210379 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810380
10381 std::string response_data;
bnc691fda62016-08-12 00:43:1610382 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810383 EXPECT_EQ("hello world", response_data);
10384
zhongyic4de03032017-05-19 04:07:3410385 EXPECT_TRUE(
10386 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810387}
10388
bncd16676a2016-07-20 16:23:0110389TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210390 MockRead data_reads[] = {
10391 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310392 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10393 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210394 MockRead("hello world"),
10395 MockRead(SYNCHRONOUS, OK),
10396 };
10397
10398 HttpRequestInfo request;
10399 request.method = "GET";
bncb26024382016-06-29 02:39:4510400 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210401
10402 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210403 session_deps_.socket_factory->AddSocketDataProvider(&data);
10404
bncb26024382016-06-29 02:39:4510405 SSLSocketDataProvider ssl(ASYNC, OK);
10406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10407
bncc958faa2015-07-31 18:14:5210408 TestCompletionCallback callback;
10409
danakj1fd259a02016-04-16 03:17:0910410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210412
tfarina42834112016-09-22 13:38:2010413 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210415
bncb26024382016-06-29 02:39:4510416 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010417 HttpServerProperties* http_server_properties =
10418 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410419 EXPECT_TRUE(
10420 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210421
robpercival214763f2016-07-01 23:27:0110422 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210423
bnc691fda62016-08-12 00:43:1610424 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210425 ASSERT_TRUE(response);
10426 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210427 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10428 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210429 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210430
10431 std::string response_data;
bnc691fda62016-08-12 00:43:1610432 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210433 EXPECT_EQ("hello world", response_data);
10434
zhongyic4de03032017-05-19 04:07:3410435 AlternativeServiceInfoVector alternative_service_info_vector =
10436 http_server_properties->GetAlternativeServiceInfos(test_server);
10437 ASSERT_EQ(2u, alternative_service_info_vector.size());
10438
10439 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
10440 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410441 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410442 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10443 1234);
10444 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5410445 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5210446}
10447
bncd16676a2016-07-20 16:23:0110448TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610449 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210450 HostPortPair alternative("alternative.example.org", 443);
10451 std::string origin_url = "https://origin.example.org:443";
10452 std::string alternative_url = "https://alternative.example.org:443";
10453
10454 // Negotiate HTTP/1.1 with alternative.example.org.
10455 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610456 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10458
10459 // HTTP/1.1 data for request.
10460 MockWrite http_writes[] = {
10461 MockWrite("GET / HTTP/1.1\r\n"
10462 "Host: alternative.example.org\r\n"
10463 "Connection: keep-alive\r\n\r\n"),
10464 };
10465
10466 MockRead http_reads[] = {
10467 MockRead("HTTP/1.1 200 OK\r\n"
10468 "Content-Type: text/html; charset=iso-8859-1\r\n"
10469 "Content-Length: 40\r\n\r\n"
10470 "first HTTP/1.1 response from alternative"),
10471 };
10472 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10473 http_writes, arraysize(http_writes));
10474 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10475
10476 StaticSocketDataProvider data_refused;
10477 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10478 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10479
zhongyi3d4a55e72016-04-22 20:36:4610480 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010482 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210483 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110484 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210485 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110486 http_server_properties->SetQuicAlternativeService(
10487 server, alternative_service, expiration,
10488 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0210489 // Mark the QUIC alternative service as broken.
10490 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10491
zhongyi48704c182015-12-07 07:52:0210492 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610493 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210494 request.method = "GET";
10495 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210496 TestCompletionCallback callback;
10497 NetErrorDetails details;
10498 EXPECT_FALSE(details.quic_broken);
10499
tfarina42834112016-09-22 13:38:2010500 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610501 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210502 EXPECT_TRUE(details.quic_broken);
10503}
10504
bncd16676a2016-07-20 16:23:0110505TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610506 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210507 HostPortPair alternative1("alternative1.example.org", 443);
10508 HostPortPair alternative2("alternative2.example.org", 443);
10509 std::string origin_url = "https://origin.example.org:443";
10510 std::string alternative_url1 = "https://alternative1.example.org:443";
10511 std::string alternative_url2 = "https://alternative2.example.org:443";
10512
10513 // Negotiate HTTP/1.1 with alternative1.example.org.
10514 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610515 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210516 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10517
10518 // HTTP/1.1 data for request.
10519 MockWrite http_writes[] = {
10520 MockWrite("GET / HTTP/1.1\r\n"
10521 "Host: alternative1.example.org\r\n"
10522 "Connection: keep-alive\r\n\r\n"),
10523 };
10524
10525 MockRead http_reads[] = {
10526 MockRead("HTTP/1.1 200 OK\r\n"
10527 "Content-Type: text/html; charset=iso-8859-1\r\n"
10528 "Content-Length: 40\r\n\r\n"
10529 "first HTTP/1.1 response from alternative1"),
10530 };
10531 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10532 http_writes, arraysize(http_writes));
10533 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10534
10535 StaticSocketDataProvider data_refused;
10536 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10537 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10538
danakj1fd259a02016-04-16 03:17:0910539 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010540 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210541 session->http_server_properties();
10542
zhongyi3d4a55e72016-04-22 20:36:4610543 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210544 AlternativeServiceInfoVector alternative_service_info_vector;
10545 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10546
bnc3472afd2016-11-17 15:27:2110547 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2110548 alternative_service_info_vector.push_back(
10549 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10550 alternative_service1, expiration,
10551 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2110552 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2110553 alternative_service_info_vector.push_back(
10554 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10555 alternative_service2, expiration,
10556 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0210557
10558 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610559 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210560
10561 // Mark one of the QUIC alternative service as broken.
10562 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410563 EXPECT_EQ(2u,
10564 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210565
zhongyi48704c182015-12-07 07:52:0210566 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610567 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210568 request.method = "GET";
10569 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210570 TestCompletionCallback callback;
10571 NetErrorDetails details;
10572 EXPECT_FALSE(details.quic_broken);
10573
tfarina42834112016-09-22 13:38:2010574 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610575 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210576 EXPECT_FALSE(details.quic_broken);
10577}
10578
bncd16676a2016-07-20 16:23:0110579TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210580 HttpRequestInfo request;
10581 request.method = "GET";
bncb26024382016-06-29 02:39:4510582 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210583
[email protected]d973e99a2012-02-17 21:02:3610584 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210585 StaticSocketDataProvider first_data;
10586 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710587 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510588 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610589 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210591
10592 MockRead data_reads[] = {
10593 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10594 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610595 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210596 };
10597 StaticSocketDataProvider second_data(
10598 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710599 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210600
danakj1fd259a02016-04-16 03:17:0910601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210602
bnc525e175a2016-06-20 12:36:4010603 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310604 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610605 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110606 // Port must be < 1024, or the header will be ignored (since initial port was
10607 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2110608 // Port is ignored by MockConnect anyway.
10609 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10610 666);
bnc7dc7e1b42015-07-28 14:43:1210611 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110612 http_server_properties->SetHttp2AlternativeService(
10613 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4210614
bnc691fda62016-08-12 00:43:1610615 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110616 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210617
tfarina42834112016-09-22 13:38:2010618 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10620 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210621
bnc691fda62016-08-12 00:43:1610622 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210623 ASSERT_TRUE(response);
10624 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210625 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10626
10627 std::string response_data;
bnc691fda62016-08-12 00:43:1610628 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210629 EXPECT_EQ("hello world", response_data);
10630
zhongyic4de03032017-05-19 04:07:3410631 const AlternativeServiceInfoVector alternative_service_info_vector =
10632 http_server_properties->GetAlternativeServiceInfos(server);
10633 ASSERT_EQ(1u, alternative_service_info_vector.size());
10634 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410635 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410636 EXPECT_TRUE(
10637 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210638}
10639
bnc55ff9da2015-08-19 18:42:3510640// Ensure that we are not allowed to redirect traffic via an alternate protocol
10641// to an unrestricted (port >= 1024) when the original traffic was on a
10642// restricted port (port < 1024). Ensure that we can redirect in all other
10643// cases.
bncd16676a2016-07-20 16:23:0110644TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110645 HttpRequestInfo restricted_port_request;
10646 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510647 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110648 restricted_port_request.load_flags = 0;
10649
[email protected]d973e99a2012-02-17 21:02:3610650 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110651 StaticSocketDataProvider first_data;
10652 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710653 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110654
10655 MockRead data_reads[] = {
10656 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10657 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610658 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110659 };
10660 StaticSocketDataProvider second_data(
10661 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710662 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510663 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610664 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510665 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110666
danakj1fd259a02016-04-16 03:17:0910667 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110668
bnc525e175a2016-06-20 12:36:4010669 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310670 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110671 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110672 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10673 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210674 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110675 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610676 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010677 expiration);
[email protected]3912662a32011-10-04 00:51:1110678
bnc691fda62016-08-12 00:43:1610679 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110680 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110681
tfarina42834112016-09-22 13:38:2010682 int rv = trans.Start(&restricted_port_request, callback.callback(),
10683 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110684 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110685 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110686 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910687}
[email protected]3912662a32011-10-04 00:51:1110688
bnc55ff9da2015-08-19 18:42:3510689// Ensure that we are allowed to redirect traffic via an alternate protocol to
10690// an unrestricted (port >= 1024) when the original traffic was on a restricted
10691// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110692TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710693 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910694
10695 HttpRequestInfo restricted_port_request;
10696 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510697 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910698 restricted_port_request.load_flags = 0;
10699
10700 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10701 StaticSocketDataProvider first_data;
10702 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710703 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910704
10705 MockRead data_reads[] = {
10706 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10707 MockRead("hello world"),
10708 MockRead(ASYNC, OK),
10709 };
10710 StaticSocketDataProvider second_data(
10711 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710712 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510713 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610714 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910716
danakj1fd259a02016-04-16 03:17:0910717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910718
bnc525e175a2016-06-20 12:36:4010719 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910720 session->http_server_properties();
10721 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110722 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10723 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210724 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110725 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610726 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010727 expiration);
[email protected]c54c6962013-02-01 04:53:1910728
bnc691fda62016-08-12 00:43:1610729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910730 TestCompletionCallback callback;
10731
tfarina42834112016-09-22 13:38:2010732 EXPECT_EQ(ERR_IO_PENDING,
10733 trans.Start(&restricted_port_request, callback.callback(),
10734 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910735 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110736 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110737}
10738
bnc55ff9da2015-08-19 18:42:3510739// Ensure that we are not allowed to redirect traffic via an alternate protocol
10740// to an unrestricted (port >= 1024) when the original traffic was on a
10741// restricted port (port < 1024). Ensure that we can redirect in all other
10742// cases.
bncd16676a2016-07-20 16:23:0110743TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110744 HttpRequestInfo restricted_port_request;
10745 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510746 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110747 restricted_port_request.load_flags = 0;
10748
[email protected]d973e99a2012-02-17 21:02:3610749 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110750 StaticSocketDataProvider first_data;
10751 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710752 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110753
10754 MockRead data_reads[] = {
10755 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10756 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610757 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110758 };
10759 StaticSocketDataProvider second_data(
10760 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710761 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110762
bncb26024382016-06-29 02:39:4510763 SSLSocketDataProvider ssl(ASYNC, OK);
10764 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10765
danakj1fd259a02016-04-16 03:17:0910766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110767
bnc525e175a2016-06-20 12:36:4010768 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310769 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110770 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110771 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10772 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210773 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110774 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610775 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010776 expiration);
[email protected]3912662a32011-10-04 00:51:1110777
bnc691fda62016-08-12 00:43:1610778 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110779 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110780
tfarina42834112016-09-22 13:38:2010781 int rv = trans.Start(&restricted_port_request, callback.callback(),
10782 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110784 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110785 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110786}
10787
bnc55ff9da2015-08-19 18:42:3510788// Ensure that we are not allowed to redirect traffic via an alternate protocol
10789// to an unrestricted (port >= 1024) when the original traffic was on a
10790// restricted port (port < 1024). Ensure that we can redirect in all other
10791// cases.
bncd16676a2016-07-20 16:23:0110792TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110793 HttpRequestInfo unrestricted_port_request;
10794 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510795 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110796 unrestricted_port_request.load_flags = 0;
10797
[email protected]d973e99a2012-02-17 21:02:3610798 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110799 StaticSocketDataProvider first_data;
10800 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710801 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110802
10803 MockRead data_reads[] = {
10804 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10805 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610806 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110807 };
10808 StaticSocketDataProvider second_data(
10809 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710810 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510811 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610812 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510813 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110814
danakj1fd259a02016-04-16 03:17:0910815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110816
bnc525e175a2016-06-20 12:36:4010817 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310818 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110819 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110820 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10821 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210822 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110823 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610824 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010825 expiration);
[email protected]3912662a32011-10-04 00:51:1110826
bnc691fda62016-08-12 00:43:1610827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110828 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110829
bnc691fda62016-08-12 00:43:1610830 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010831 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110833 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110834 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110835}
10836
bnc55ff9da2015-08-19 18:42:3510837// Ensure that we are not allowed to redirect traffic via an alternate protocol
10838// to an unrestricted (port >= 1024) when the original traffic was on a
10839// restricted port (port < 1024). Ensure that we can redirect in all other
10840// cases.
bncd16676a2016-07-20 16:23:0110841TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110842 HttpRequestInfo unrestricted_port_request;
10843 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510844 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110845 unrestricted_port_request.load_flags = 0;
10846
[email protected]d973e99a2012-02-17 21:02:3610847 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110848 StaticSocketDataProvider first_data;
10849 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710850 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110851
10852 MockRead data_reads[] = {
10853 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10854 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610855 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110856 };
10857 StaticSocketDataProvider second_data(
10858 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710859 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110860
bncb26024382016-06-29 02:39:4510861 SSLSocketDataProvider ssl(ASYNC, OK);
10862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10863
danakj1fd259a02016-04-16 03:17:0910864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110865
bnc525e175a2016-06-20 12:36:4010866 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310867 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210868 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110869 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10870 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210871 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110872 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610873 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010874 expiration);
[email protected]3912662a32011-10-04 00:51:1110875
bnc691fda62016-08-12 00:43:1610876 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110877 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110878
bnc691fda62016-08-12 00:43:1610879 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010880 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110882 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110883 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110884}
10885
bnc55ff9da2015-08-19 18:42:3510886// Ensure that we are not allowed to redirect traffic via an alternate protocol
10887// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10888// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110889TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210890 HttpRequestInfo request;
10891 request.method = "GET";
bncce36dca22015-04-21 22:11:2310892 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210893
10894 // The alternate protocol request will error out before we attempt to connect,
10895 // so only the standard HTTP request will try to connect.
10896 MockRead data_reads[] = {
10897 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10898 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610899 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210900 };
10901 StaticSocketDataProvider data(
10902 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710903 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210904
danakj1fd259a02016-04-16 03:17:0910905 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210906
bnc525e175a2016-06-20 12:36:4010907 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210908 session->http_server_properties();
10909 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110910 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10911 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210912 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110913 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610914 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210915
bnc691fda62016-08-12 00:43:1610916 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210917 TestCompletionCallback callback;
10918
tfarina42834112016-09-22 13:38:2010919 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210921 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110922 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210923
bnc691fda62016-08-12 00:43:1610924 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210925 ASSERT_TRUE(response);
10926 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210927 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10928
10929 std::string response_data;
bnc691fda62016-08-12 00:43:1610930 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210931 EXPECT_EQ("hello world", response_data);
10932}
10933
bncd16676a2016-07-20 16:23:0110934TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410935 HttpRequestInfo request;
10936 request.method = "GET";
bncb26024382016-06-29 02:39:4510937 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410938
10939 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210940 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310941 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210942 MockRead("\r\n"),
10943 MockRead("hello world"),
10944 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10945 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410946
10947 StaticSocketDataProvider first_transaction(
10948 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710949 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510950 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610951 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510952 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410953
bnc032658ba2016-09-26 18:17:1510954 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410955
bncdf80d44fd2016-07-15 20:27:4110956 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510957 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110958 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410959
bnc42331402016-07-25 13:36:1510960 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110961 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410962 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110963 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410964 };
10965
rch8e6c6c42015-05-01 14:05:1310966 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10967 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710968 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410969
[email protected]d973e99a2012-02-17 21:02:3610970 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510971 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10972 NULL, 0, NULL, 0);
10973 hanging_non_alternate_protocol_socket.set_connect_data(
10974 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710975 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510976 &hanging_non_alternate_protocol_socket);
10977
[email protected]49639fa2011-12-20 23:22:4110978 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410979
danakj1fd259a02016-04-16 03:17:0910980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810981 auto trans =
10982 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410983
tfarina42834112016-09-22 13:38:2010984 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10986 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410987
10988 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210989 ASSERT_TRUE(response);
10990 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410991 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10992
10993 std::string response_data;
robpercival214763f2016-07-01 23:27:0110994 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410995 EXPECT_EQ("hello world", response_data);
10996
bnc87dcefc2017-05-25 12:47:5810997 trans =
10998 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410999
tfarina42834112016-09-22 13:38:2011000 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11002 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411003
11004 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211005 ASSERT_TRUE(response);
11006 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211007 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311008 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211009 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411010
robpercival214763f2016-07-01 23:27:0111011 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411012 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411013}
11014
bncd16676a2016-07-20 16:23:0111015TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511016 HttpRequestInfo request;
11017 request.method = "GET";
bncb26024382016-06-29 02:39:4511018 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511019
bncb26024382016-06-29 02:39:4511020 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511021 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211022 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311023 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211024 MockRead("\r\n"),
11025 MockRead("hello world"),
11026 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11027 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511028 };
11029
bncb26024382016-06-29 02:39:4511030 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11031 0);
11032 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511033
bncb26024382016-06-29 02:39:4511034 SSLSocketDataProvider ssl_http11(ASYNC, OK);
11035 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11036
11037 // Second transaction starts an alternative and a non-alternative Job.
11038 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611039 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811040 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11041 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811042 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11043
11044 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11045 hanging_socket2.set_connect_data(never_finishing_connect);
11046 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511047
bncb26024382016-06-29 02:39:4511048 // Third transaction starts an alternative and a non-alternative job.
11049 // The non-alternative job hangs, but the alternative one succeeds.
11050 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111051 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511052 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111053 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511054 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511055 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111056 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511057 };
bnc42331402016-07-25 13:36:1511058 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111059 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511060 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111061 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511062 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111063 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11064 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311065 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511066 };
11067
rch8e6c6c42015-05-01 14:05:1311068 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11069 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711070 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511071
bnc032658ba2016-09-26 18:17:1511072 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511073
mmenkecc2298e2015-12-07 18:20:1811074 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11075 hanging_socket3.set_connect_data(never_finishing_connect);
11076 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511077
danakj1fd259a02016-04-16 03:17:0911078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111079 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011080 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511081
tfarina42834112016-09-22 13:38:2011082 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11084 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511085
11086 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211087 ASSERT_TRUE(response);
11088 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511089 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11090
11091 std::string response_data;
robpercival214763f2016-07-01 23:27:0111092 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511093 EXPECT_EQ("hello world", response_data);
11094
[email protected]49639fa2011-12-20 23:22:4111095 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011096 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011097 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511099
[email protected]49639fa2011-12-20 23:22:4111100 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011101 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011102 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511104
robpercival214763f2016-07-01 23:27:0111105 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11106 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511107
11108 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211109 ASSERT_TRUE(response);
11110 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211111 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511112 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211113 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111114 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511115 EXPECT_EQ("hello!", response_data);
11116
11117 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211118 ASSERT_TRUE(response);
11119 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211120 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511121 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211122 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111123 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511124 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511125}
11126
bncd16676a2016-07-20 16:23:0111127TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511128 HttpRequestInfo request;
11129 request.method = "GET";
bncb26024382016-06-29 02:39:4511130 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511131
11132 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211133 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311134 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211135 MockRead("\r\n"),
11136 MockRead("hello world"),
11137 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11138 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511139 };
11140
11141 StaticSocketDataProvider first_transaction(
11142 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711143 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511144
[email protected]8ddf8322012-02-23 18:08:0611145 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511147
[email protected]d973e99a2012-02-17 21:02:3611148 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511149 StaticSocketDataProvider hanging_alternate_protocol_socket(
11150 NULL, 0, NULL, 0);
11151 hanging_alternate_protocol_socket.set_connect_data(
11152 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711153 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511154 &hanging_alternate_protocol_socket);
11155
bncb26024382016-06-29 02:39:4511156 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811157 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11158 NULL, 0);
11159 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511161
[email protected]49639fa2011-12-20 23:22:4111162 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511163
danakj1fd259a02016-04-16 03:17:0911164 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811165 auto trans =
11166 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511167
tfarina42834112016-09-22 13:38:2011168 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111169 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11170 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511171
11172 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211173 ASSERT_TRUE(response);
11174 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511175 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11176
11177 std::string response_data;
robpercival214763f2016-07-01 23:27:0111178 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511179 EXPECT_EQ("hello world", response_data);
11180
bnc87dcefc2017-05-25 12:47:5811181 trans =
11182 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511183
tfarina42834112016-09-22 13:38:2011184 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11186 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511187
11188 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211189 ASSERT_TRUE(response);
11190 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511191 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11192 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211193 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511194
robpercival214763f2016-07-01 23:27:0111195 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511196 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511197}
11198
[email protected]631f1322010-04-30 17:59:1111199class CapturingProxyResolver : public ProxyResolver {
11200 public:
sammce90c9212015-05-27 23:43:3511201 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011202 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111203
dchengb03027d2014-10-21 12:00:2011204 int GetProxyForURL(const GURL& url,
11205 ProxyInfo* results,
11206 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511207 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011208 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011209 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11210 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211211 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111212 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211213 return OK;
[email protected]631f1322010-04-30 17:59:1111214 }
11215
[email protected]24476402010-07-20 20:55:1711216 const std::vector<GURL>& resolved() const { return resolved_; }
11217
11218 private:
[email protected]631f1322010-04-30 17:59:1111219 std::vector<GURL> resolved_;
11220
11221 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11222};
11223
sammce64b2362015-04-29 03:50:2311224class CapturingProxyResolverFactory : public ProxyResolverFactory {
11225 public:
11226 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11227 : ProxyResolverFactory(false), resolver_(resolver) {}
11228
11229 int CreateProxyResolver(
11230 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911231 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311232 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911233 std::unique_ptr<Request>* request) override {
bnc87dcefc2017-05-25 12:47:5811234 *resolver = base::MakeUnique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311235 return OK;
11236 }
11237
11238 private:
11239 ProxyResolver* resolver_;
11240};
11241
bnc2e884782016-08-11 19:45:1911242// Test that proxy is resolved using the origin url,
11243// regardless of the alternative server.
11244TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11245 // Configure proxy to bypass www.example.org, which is the origin URL.
11246 ProxyConfig proxy_config;
11247 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11248 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11249 auto proxy_config_service =
11250 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11251
11252 CapturingProxyResolver capturing_proxy_resolver;
11253 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11254 &capturing_proxy_resolver);
11255
11256 TestNetLog net_log;
11257
11258 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11259 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11260 &net_log);
11261
11262 session_deps_.net_log = &net_log;
11263
11264 // Configure alternative service with a hostname that is not bypassed by the
11265 // proxy.
11266 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11267 HttpServerProperties* http_server_properties =
11268 session->http_server_properties();
11269 url::SchemeHostPort server("https", "www.example.org", 443);
11270 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111271 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911272 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111273 http_server_properties->SetHttp2AlternativeService(
11274 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911275
11276 // Non-alternative job should hang.
11277 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11278 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11279 nullptr, 0);
11280 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11281 session_deps_.socket_factory->AddSocketDataProvider(
11282 &hanging_alternate_protocol_socket);
11283
bnc032658ba2016-09-26 18:17:1511284 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911285
11286 HttpRequestInfo request;
11287 request.method = "GET";
11288 request.url = GURL("https://www.example.org/");
11289 request.load_flags = 0;
11290
11291 SpdySerializedFrame req(
11292 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11293
11294 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11295
11296 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11297 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11298 MockRead spdy_reads[] = {
11299 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11300 };
11301
11302 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11303 arraysize(spdy_writes));
11304 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11305
11306 TestCompletionCallback callback;
11307
11308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11309
tfarina42834112016-09-22 13:38:2011310 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911311 EXPECT_THAT(callback.GetResult(rv), IsOk());
11312
11313 const HttpResponseInfo* response = trans.GetResponseInfo();
11314 ASSERT_TRUE(response);
11315 ASSERT_TRUE(response->headers);
11316 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11317 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211318 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911319
11320 std::string response_data;
11321 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11322 EXPECT_EQ("hello!", response_data);
11323
11324 // Origin host bypasses proxy, no resolution should have happened.
11325 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11326}
11327
bncd16676a2016-07-20 16:23:0111328TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111329 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211330 proxy_config.set_auto_detect(true);
11331 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111332
sammc5dd160c2015-04-02 02:43:1311333 CapturingProxyResolver capturing_proxy_resolver;
bnc87dcefc2017-05-25 12:47:5811334 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11335 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11336 base::MakeUnique<CapturingProxyResolverFactory>(
11337 &capturing_proxy_resolver),
11338 nullptr);
vishal.b62985ca92015-04-17 08:45:5111339 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711340 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111341
11342 HttpRequestInfo request;
11343 request.method = "GET";
bncb26024382016-06-29 02:39:4511344 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111345
11346 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211347 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311348 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211349 MockRead("\r\n"),
11350 MockRead("hello world"),
11351 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11352 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111353 };
11354
11355 StaticSocketDataProvider first_transaction(
11356 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711357 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511358 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611359 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111361
bnc032658ba2016-09-26 18:17:1511362 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111363
bncdf80d44fd2016-07-15 20:27:4111364 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511365 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111366 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311367 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511368 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11369 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311370 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111371 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111372 };
11373
[email protected]d911f1b2010-05-05 22:39:4211374 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11375
bnc42331402016-07-25 13:36:1511376 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111377 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111378 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111379 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11380 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111381 };
11382
rch8e6c6c42015-05-01 14:05:1311383 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11384 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711385 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111386
[email protected]d973e99a2012-02-17 21:02:3611387 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511388 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11389 NULL, 0, NULL, 0);
11390 hanging_non_alternate_protocol_socket.set_connect_data(
11391 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711392 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511393 &hanging_non_alternate_protocol_socket);
11394
[email protected]49639fa2011-12-20 23:22:4111395 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111396
danakj1fd259a02016-04-16 03:17:0911397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811398 auto trans =
11399 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111400
tfarina42834112016-09-22 13:38:2011401 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111402 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11403 EXPECT_THAT(callback.WaitForResult(), IsOk());
11404
11405 const HttpResponseInfo* response = trans->GetResponseInfo();
11406 ASSERT_TRUE(response);
11407 ASSERT_TRUE(response->headers);
11408 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11409 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211410 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111411
11412 std::string response_data;
11413 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11414 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111415
bnc87dcefc2017-05-25 12:47:5811416 trans =
11417 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111418
tfarina42834112016-09-22 13:38:2011419 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11421 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111422
mmenkea2dcd3bf2016-08-16 21:49:4111423 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211424 ASSERT_TRUE(response);
11425 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211426 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311427 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211428 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111429
robpercival214763f2016-07-01 23:27:0111430 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111431 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511432 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11433 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311434 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311435 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311436 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111437
[email protected]029c83b62013-01-24 05:28:2011438 LoadTimingInfo load_timing_info;
11439 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11440 TestLoadTimingNotReusedWithPac(load_timing_info,
11441 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111442}
[email protected]631f1322010-04-30 17:59:1111443
bncd16676a2016-07-20 16:23:0111444TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811445 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411446 HttpRequestInfo request;
11447 request.method = "GET";
bncb26024382016-06-29 02:39:4511448 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411449
11450 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211451 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311452 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211453 MockRead("\r\n"),
11454 MockRead("hello world"),
11455 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411456 };
11457
11458 StaticSocketDataProvider first_transaction(
11459 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711460 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511461 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611462 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511463 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411464
bnc032658ba2016-09-26 18:17:1511465 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411466
bncdf80d44fd2016-07-15 20:27:4111467 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511468 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111469 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411470
bnc42331402016-07-25 13:36:1511471 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111472 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411473 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111474 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411475 };
11476
rch8e6c6c42015-05-01 14:05:1311477 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11478 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711479 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411480
[email protected]83039bb2011-12-09 18:43:5511481 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411482
danakj1fd259a02016-04-16 03:17:0911483 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411484
bnc87dcefc2017-05-25 12:47:5811485 auto trans =
11486 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411487
tfarina42834112016-09-22 13:38:2011488 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11490 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411491
11492 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211493 ASSERT_TRUE(response);
11494 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411495 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11496
11497 std::string response_data;
robpercival214763f2016-07-01 23:27:0111498 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411499 EXPECT_EQ("hello world", response_data);
11500
11501 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511502 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011503 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311504 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711505 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5211506 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811507
bnc87dcefc2017-05-25 12:47:5811508 trans =
11509 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411510
tfarina42834112016-09-22 13:38:2011511 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11513 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411514
11515 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211516 ASSERT_TRUE(response);
11517 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211518 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311519 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211520 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411521
robpercival214763f2016-07-01 23:27:0111522 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411523 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211524}
11525
[email protected]044de0642010-06-17 10:42:1511526// GenerateAuthToken is a mighty big test.
11527// It tests all permutation of GenerateAuthToken behavior:
11528// - Synchronous and Asynchronous completion.
11529// - OK or error on completion.
11530// - Direct connection, non-authenticating proxy, and authenticating proxy.
11531// - HTTP or HTTPS backend (to include proxy tunneling).
11532// - Non-authenticating and authenticating backend.
11533//
[email protected]fe3b7dc2012-02-03 19:52:0911534// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511535// problems generating an auth token for an authenticating proxy, we don't
11536// need to test all permutations of the backend server).
11537//
11538// The test proceeds by going over each of the configuration cases, and
11539// potentially running up to three rounds in each of the tests. The TestConfig
11540// specifies both the configuration for the test as well as the expectations
11541// for the results.
bncd16676a2016-07-20 16:23:0111542TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011543 static const char kServer[] = "http://www.example.com";
11544 static const char kSecureServer[] = "https://www.example.com";
11545 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511546
11547 enum AuthTiming {
11548 AUTH_NONE,
11549 AUTH_SYNC,
11550 AUTH_ASYNC,
11551 };
11552
11553 const MockWrite kGet(
11554 "GET / HTTP/1.1\r\n"
11555 "Host: www.example.com\r\n"
11556 "Connection: keep-alive\r\n\r\n");
11557 const MockWrite kGetProxy(
11558 "GET http://www.example.com/ HTTP/1.1\r\n"
11559 "Host: www.example.com\r\n"
11560 "Proxy-Connection: keep-alive\r\n\r\n");
11561 const MockWrite kGetAuth(
11562 "GET / HTTP/1.1\r\n"
11563 "Host: www.example.com\r\n"
11564 "Connection: keep-alive\r\n"
11565 "Authorization: auth_token\r\n\r\n");
11566 const MockWrite kGetProxyAuth(
11567 "GET http://www.example.com/ HTTP/1.1\r\n"
11568 "Host: www.example.com\r\n"
11569 "Proxy-Connection: keep-alive\r\n"
11570 "Proxy-Authorization: auth_token\r\n\r\n");
11571 const MockWrite kGetAuthThroughProxy(
11572 "GET http://www.example.com/ HTTP/1.1\r\n"
11573 "Host: www.example.com\r\n"
11574 "Proxy-Connection: keep-alive\r\n"
11575 "Authorization: auth_token\r\n\r\n");
11576 const MockWrite kGetAuthWithProxyAuth(
11577 "GET http://www.example.com/ HTTP/1.1\r\n"
11578 "Host: www.example.com\r\n"
11579 "Proxy-Connection: keep-alive\r\n"
11580 "Proxy-Authorization: auth_token\r\n"
11581 "Authorization: auth_token\r\n\r\n");
11582 const MockWrite kConnect(
11583 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711584 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511585 "Proxy-Connection: keep-alive\r\n\r\n");
11586 const MockWrite kConnectProxyAuth(
11587 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711588 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511589 "Proxy-Connection: keep-alive\r\n"
11590 "Proxy-Authorization: auth_token\r\n\r\n");
11591
11592 const MockRead kSuccess(
11593 "HTTP/1.1 200 OK\r\n"
11594 "Content-Type: text/html; charset=iso-8859-1\r\n"
11595 "Content-Length: 3\r\n\r\n"
11596 "Yes");
11597 const MockRead kFailure(
11598 "Should not be called.");
11599 const MockRead kServerChallenge(
11600 "HTTP/1.1 401 Unauthorized\r\n"
11601 "WWW-Authenticate: Mock realm=server\r\n"
11602 "Content-Type: text/html; charset=iso-8859-1\r\n"
11603 "Content-Length: 14\r\n\r\n"
11604 "Unauthorized\r\n");
11605 const MockRead kProxyChallenge(
11606 "HTTP/1.1 407 Unauthorized\r\n"
11607 "Proxy-Authenticate: Mock realm=proxy\r\n"
11608 "Proxy-Connection: close\r\n"
11609 "Content-Type: text/html; charset=iso-8859-1\r\n"
11610 "Content-Length: 14\r\n\r\n"
11611 "Unauthorized\r\n");
11612 const MockRead kProxyConnected(
11613 "HTTP/1.1 200 Connection Established\r\n\r\n");
11614
11615 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11616 // no constructors, but the C++ compiler on Windows warns about
11617 // unspecified data in compound literals. So, moved to using constructors,
11618 // and TestRound's created with the default constructor should not be used.
11619 struct TestRound {
11620 TestRound()
11621 : expected_rv(ERR_UNEXPECTED),
11622 extra_write(NULL),
11623 extra_read(NULL) {
11624 }
11625 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11626 int expected_rv_arg)
11627 : write(write_arg),
11628 read(read_arg),
11629 expected_rv(expected_rv_arg),
11630 extra_write(NULL),
11631 extra_read(NULL) {
11632 }
11633 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11634 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111635 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511636 : write(write_arg),
11637 read(read_arg),
11638 expected_rv(expected_rv_arg),
11639 extra_write(extra_write_arg),
11640 extra_read(extra_read_arg) {
11641 }
11642 MockWrite write;
11643 MockRead read;
11644 int expected_rv;
11645 const MockWrite* extra_write;
11646 const MockRead* extra_read;
11647 };
11648
11649 static const int kNoSSL = 500;
11650
11651 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111652 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111653 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511654 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111655 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111656 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511657 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111658 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511659 int num_auth_rounds;
11660 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611661 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511662 } test_configs[] = {
asankac93076192016-10-03 15:46:0211663 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111664 {__LINE__,
11665 nullptr,
asankac93076192016-10-03 15:46:0211666 AUTH_NONE,
11667 OK,
11668 kServer,
11669 AUTH_NONE,
11670 OK,
11671 1,
11672 kNoSSL,
11673 {TestRound(kGet, kSuccess, OK)}},
11674 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111675 {__LINE__,
11676 nullptr,
asankac93076192016-10-03 15:46:0211677 AUTH_NONE,
11678 OK,
11679 kServer,
11680 AUTH_SYNC,
11681 OK,
11682 2,
11683 kNoSSL,
11684 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511685 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111686 {__LINE__,
11687 nullptr,
asankac93076192016-10-03 15:46:0211688 AUTH_NONE,
11689 OK,
11690 kServer,
11691 AUTH_SYNC,
11692 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611693 3,
11694 kNoSSL,
11695 {TestRound(kGet, kServerChallenge, OK),
11696 TestRound(kGet, kServerChallenge, OK),
11697 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111698 {__LINE__,
11699 nullptr,
asankae2257db2016-10-11 22:03:1611700 AUTH_NONE,
11701 OK,
11702 kServer,
11703 AUTH_SYNC,
11704 ERR_UNSUPPORTED_AUTH_SCHEME,
11705 2,
11706 kNoSSL,
11707 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111708 {__LINE__,
11709 nullptr,
asankae2257db2016-10-11 22:03:1611710 AUTH_NONE,
11711 OK,
11712 kServer,
11713 AUTH_SYNC,
11714 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11715 2,
11716 kNoSSL,
11717 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111718 {__LINE__,
11719 kProxy,
asankae2257db2016-10-11 22:03:1611720 AUTH_SYNC,
11721 ERR_FAILED,
11722 kServer,
11723 AUTH_NONE,
11724 OK,
11725 2,
11726 kNoSSL,
11727 {TestRound(kGetProxy, kProxyChallenge, OK),
11728 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111729 {__LINE__,
11730 kProxy,
asankae2257db2016-10-11 22:03:1611731 AUTH_ASYNC,
11732 ERR_FAILED,
11733 kServer,
11734 AUTH_NONE,
11735 OK,
11736 2,
11737 kNoSSL,
11738 {TestRound(kGetProxy, kProxyChallenge, OK),
11739 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111740 {__LINE__,
11741 nullptr,
asankae2257db2016-10-11 22:03:1611742 AUTH_NONE,
11743 OK,
11744 kServer,
11745 AUTH_SYNC,
11746 ERR_FAILED,
asankac93076192016-10-03 15:46:0211747 2,
11748 kNoSSL,
11749 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611750 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111751 {__LINE__,
11752 nullptr,
asankae2257db2016-10-11 22:03:1611753 AUTH_NONE,
11754 OK,
11755 kServer,
11756 AUTH_ASYNC,
11757 ERR_FAILED,
11758 2,
11759 kNoSSL,
11760 {TestRound(kGet, kServerChallenge, OK),
11761 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111762 {__LINE__,
11763 nullptr,
asankac93076192016-10-03 15:46:0211764 AUTH_NONE,
11765 OK,
11766 kServer,
11767 AUTH_ASYNC,
11768 OK,
11769 2,
11770 kNoSSL,
11771 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511772 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111773 {__LINE__,
11774 nullptr,
asankac93076192016-10-03 15:46:0211775 AUTH_NONE,
11776 OK,
11777 kServer,
11778 AUTH_ASYNC,
11779 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611780 3,
asankac93076192016-10-03 15:46:0211781 kNoSSL,
11782 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611783 // The second round uses a HttpAuthHandlerMock that always succeeds.
11784 TestRound(kGet, kServerChallenge, OK),
11785 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211786 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111787 {__LINE__,
11788 kProxy,
asankac93076192016-10-03 15:46:0211789 AUTH_NONE,
11790 OK,
11791 kServer,
11792 AUTH_NONE,
11793 OK,
11794 1,
11795 kNoSSL,
11796 {TestRound(kGetProxy, kSuccess, OK)}},
11797 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111798 {__LINE__,
11799 kProxy,
asankac93076192016-10-03 15:46:0211800 AUTH_NONE,
11801 OK,
11802 kServer,
11803 AUTH_SYNC,
11804 OK,
11805 2,
11806 kNoSSL,
11807 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511808 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111809 {__LINE__,
11810 kProxy,
asankac93076192016-10-03 15:46:0211811 AUTH_NONE,
11812 OK,
11813 kServer,
11814 AUTH_SYNC,
11815 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611816 3,
asankac93076192016-10-03 15:46:0211817 kNoSSL,
11818 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611819 TestRound(kGetProxy, kServerChallenge, OK),
11820 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111821 {__LINE__,
11822 kProxy,
asankac93076192016-10-03 15:46:0211823 AUTH_NONE,
11824 OK,
11825 kServer,
11826 AUTH_ASYNC,
11827 OK,
11828 2,
11829 kNoSSL,
11830 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511831 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111832 {__LINE__,
11833 kProxy,
asankac93076192016-10-03 15:46:0211834 AUTH_NONE,
11835 OK,
11836 kServer,
11837 AUTH_ASYNC,
11838 ERR_INVALID_AUTH_CREDENTIALS,
11839 2,
11840 kNoSSL,
11841 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611842 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211843 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111844 {__LINE__,
11845 kProxy,
asankac93076192016-10-03 15:46:0211846 AUTH_SYNC,
11847 OK,
11848 kServer,
11849 AUTH_NONE,
11850 OK,
11851 2,
11852 kNoSSL,
11853 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511854 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111855 {__LINE__,
11856 kProxy,
asankac93076192016-10-03 15:46:0211857 AUTH_SYNC,
11858 ERR_INVALID_AUTH_CREDENTIALS,
11859 kServer,
11860 AUTH_NONE,
11861 OK,
11862 2,
11863 kNoSSL,
11864 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611865 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111866 {__LINE__,
11867 kProxy,
asankac93076192016-10-03 15:46:0211868 AUTH_ASYNC,
11869 OK,
11870 kServer,
11871 AUTH_NONE,
11872 OK,
11873 2,
11874 kNoSSL,
11875 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511876 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111877 {__LINE__,
11878 kProxy,
asankac93076192016-10-03 15:46:0211879 AUTH_ASYNC,
11880 ERR_INVALID_AUTH_CREDENTIALS,
11881 kServer,
11882 AUTH_NONE,
11883 OK,
11884 2,
11885 kNoSSL,
11886 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611887 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111888 {__LINE__,
11889 kProxy,
11890 AUTH_ASYNC,
11891 ERR_INVALID_AUTH_CREDENTIALS,
11892 kServer,
11893 AUTH_NONE,
11894 OK,
11895 3,
11896 kNoSSL,
11897 {TestRound(kGetProxy, kProxyChallenge, OK),
11898 TestRound(kGetProxy, kProxyChallenge, OK),
11899 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211900 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111901 {__LINE__,
11902 kProxy,
asankac93076192016-10-03 15:46:0211903 AUTH_SYNC,
11904 OK,
11905 kServer,
11906 AUTH_SYNC,
11907 OK,
11908 3,
11909 kNoSSL,
11910 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511911 TestRound(kGetProxyAuth, kServerChallenge, OK),
11912 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111913 {__LINE__,
11914 kProxy,
asankac93076192016-10-03 15:46:0211915 AUTH_SYNC,
11916 OK,
11917 kServer,
11918 AUTH_SYNC,
11919 ERR_INVALID_AUTH_CREDENTIALS,
11920 3,
11921 kNoSSL,
11922 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511923 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611924 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111925 {__LINE__,
11926 kProxy,
asankac93076192016-10-03 15:46:0211927 AUTH_ASYNC,
11928 OK,
11929 kServer,
11930 AUTH_SYNC,
11931 OK,
11932 3,
11933 kNoSSL,
11934 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511935 TestRound(kGetProxyAuth, kServerChallenge, OK),
11936 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111937 {__LINE__,
11938 kProxy,
asankac93076192016-10-03 15:46:0211939 AUTH_ASYNC,
11940 OK,
11941 kServer,
11942 AUTH_SYNC,
11943 ERR_INVALID_AUTH_CREDENTIALS,
11944 3,
11945 kNoSSL,
11946 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511947 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611948 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111949 {__LINE__,
11950 kProxy,
asankac93076192016-10-03 15:46:0211951 AUTH_SYNC,
11952 OK,
11953 kServer,
11954 AUTH_ASYNC,
11955 OK,
11956 3,
11957 kNoSSL,
11958 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511959 TestRound(kGetProxyAuth, kServerChallenge, OK),
11960 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111961 {__LINE__,
11962 kProxy,
11963 AUTH_SYNC,
11964 ERR_INVALID_AUTH_CREDENTIALS,
11965 kServer,
11966 AUTH_ASYNC,
11967 OK,
11968 4,
11969 kNoSSL,
11970 {TestRound(kGetProxy, kProxyChallenge, OK),
11971 TestRound(kGetProxy, kProxyChallenge, OK),
11972 TestRound(kGetProxyAuth, kServerChallenge, OK),
11973 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11974 {__LINE__,
11975 kProxy,
asankac93076192016-10-03 15:46:0211976 AUTH_SYNC,
11977 OK,
11978 kServer,
11979 AUTH_ASYNC,
11980 ERR_INVALID_AUTH_CREDENTIALS,
11981 3,
11982 kNoSSL,
11983 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511984 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611985 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111986 {__LINE__,
11987 kProxy,
asankac93076192016-10-03 15:46:0211988 AUTH_ASYNC,
11989 OK,
11990 kServer,
11991 AUTH_ASYNC,
11992 OK,
11993 3,
11994 kNoSSL,
11995 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511996 TestRound(kGetProxyAuth, kServerChallenge, OK),
11997 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111998 {__LINE__,
11999 kProxy,
asankac93076192016-10-03 15:46:0212000 AUTH_ASYNC,
12001 OK,
12002 kServer,
12003 AUTH_ASYNC,
12004 ERR_INVALID_AUTH_CREDENTIALS,
12005 3,
12006 kNoSSL,
12007 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512008 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612009 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112010 {__LINE__,
12011 kProxy,
12012 AUTH_ASYNC,
12013 ERR_INVALID_AUTH_CREDENTIALS,
12014 kServer,
12015 AUTH_ASYNC,
12016 ERR_INVALID_AUTH_CREDENTIALS,
12017 4,
12018 kNoSSL,
12019 {TestRound(kGetProxy, kProxyChallenge, OK),
12020 TestRound(kGetProxy, kProxyChallenge, OK),
12021 TestRound(kGetProxyAuth, kServerChallenge, OK),
12022 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212023 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112024 {__LINE__,
12025 nullptr,
asankac93076192016-10-03 15:46:0212026 AUTH_NONE,
12027 OK,
12028 kSecureServer,
12029 AUTH_NONE,
12030 OK,
12031 1,
12032 0,
12033 {TestRound(kGet, kSuccess, OK)}},
12034 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112035 {__LINE__,
12036 nullptr,
asankac93076192016-10-03 15:46:0212037 AUTH_NONE,
12038 OK,
12039 kSecureServer,
12040 AUTH_SYNC,
12041 OK,
12042 2,
12043 0,
12044 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512045 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112046 {__LINE__,
12047 nullptr,
asankac93076192016-10-03 15:46:0212048 AUTH_NONE,
12049 OK,
12050 kSecureServer,
12051 AUTH_SYNC,
12052 ERR_INVALID_AUTH_CREDENTIALS,
12053 2,
12054 0,
asankae2257db2016-10-11 22:03:1612055 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112056 {__LINE__,
12057 nullptr,
asankac93076192016-10-03 15:46:0212058 AUTH_NONE,
12059 OK,
12060 kSecureServer,
12061 AUTH_ASYNC,
12062 OK,
12063 2,
12064 0,
12065 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512066 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112067 {__LINE__,
12068 nullptr,
asankac93076192016-10-03 15:46:0212069 AUTH_NONE,
12070 OK,
12071 kSecureServer,
12072 AUTH_ASYNC,
12073 ERR_INVALID_AUTH_CREDENTIALS,
12074 2,
12075 0,
asankae2257db2016-10-11 22:03:1612076 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212077 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112078 {__LINE__,
12079 kProxy,
asankac93076192016-10-03 15:46:0212080 AUTH_NONE,
12081 OK,
12082 kSecureServer,
12083 AUTH_NONE,
12084 OK,
12085 1,
12086 0,
12087 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12088 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112089 {__LINE__,
12090 kProxy,
asankac93076192016-10-03 15:46:0212091 AUTH_NONE,
12092 OK,
12093 kSecureServer,
12094 AUTH_SYNC,
12095 OK,
12096 2,
12097 0,
12098 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512099 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112100 {__LINE__,
12101 kProxy,
asankac93076192016-10-03 15:46:0212102 AUTH_NONE,
12103 OK,
12104 kSecureServer,
12105 AUTH_SYNC,
12106 ERR_INVALID_AUTH_CREDENTIALS,
12107 2,
12108 0,
12109 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612110 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112111 {__LINE__,
12112 kProxy,
asankac93076192016-10-03 15:46:0212113 AUTH_NONE,
12114 OK,
12115 kSecureServer,
12116 AUTH_ASYNC,
12117 OK,
12118 2,
12119 0,
12120 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512121 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112122 {__LINE__,
12123 kProxy,
asankac93076192016-10-03 15:46:0212124 AUTH_NONE,
12125 OK,
12126 kSecureServer,
12127 AUTH_ASYNC,
12128 ERR_INVALID_AUTH_CREDENTIALS,
12129 2,
12130 0,
12131 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612132 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212133 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112134 {__LINE__,
12135 kProxy,
asankac93076192016-10-03 15:46:0212136 AUTH_SYNC,
12137 OK,
12138 kSecureServer,
12139 AUTH_NONE,
12140 OK,
12141 2,
12142 1,
12143 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512144 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112145 {__LINE__,
12146 kProxy,
asankac93076192016-10-03 15:46:0212147 AUTH_SYNC,
12148 ERR_INVALID_AUTH_CREDENTIALS,
12149 kSecureServer,
12150 AUTH_NONE,
12151 OK,
12152 2,
12153 kNoSSL,
12154 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612155 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112156 {__LINE__,
12157 kProxy,
asankae2257db2016-10-11 22:03:1612158 AUTH_SYNC,
12159 ERR_UNSUPPORTED_AUTH_SCHEME,
12160 kSecureServer,
12161 AUTH_NONE,
12162 OK,
12163 2,
12164 kNoSSL,
12165 {TestRound(kConnect, kProxyChallenge, OK),
12166 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112167 {__LINE__,
12168 kProxy,
asankae2257db2016-10-11 22:03:1612169 AUTH_SYNC,
12170 ERR_UNEXPECTED,
12171 kSecureServer,
12172 AUTH_NONE,
12173 OK,
12174 2,
12175 kNoSSL,
12176 {TestRound(kConnect, kProxyChallenge, OK),
12177 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112178 {__LINE__,
12179 kProxy,
asankac93076192016-10-03 15:46:0212180 AUTH_ASYNC,
12181 OK,
12182 kSecureServer,
12183 AUTH_NONE,
12184 OK,
12185 2,
12186 1,
12187 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512188 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112189 {__LINE__,
12190 kProxy,
asankac93076192016-10-03 15:46:0212191 AUTH_ASYNC,
12192 ERR_INVALID_AUTH_CREDENTIALS,
12193 kSecureServer,
12194 AUTH_NONE,
12195 OK,
12196 2,
12197 kNoSSL,
12198 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612199 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212200 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112201 {__LINE__,
12202 kProxy,
asankac93076192016-10-03 15:46:0212203 AUTH_SYNC,
12204 OK,
12205 kSecureServer,
12206 AUTH_SYNC,
12207 OK,
12208 3,
12209 1,
12210 {TestRound(kConnect, kProxyChallenge, OK),
12211 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12212 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512213 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112214 {__LINE__,
12215 kProxy,
asankac93076192016-10-03 15:46:0212216 AUTH_SYNC,
12217 OK,
12218 kSecureServer,
12219 AUTH_SYNC,
12220 ERR_INVALID_AUTH_CREDENTIALS,
12221 3,
12222 1,
12223 {TestRound(kConnect, kProxyChallenge, OK),
12224 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12225 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612226 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112227 {__LINE__,
12228 kProxy,
asankac93076192016-10-03 15:46:0212229 AUTH_ASYNC,
12230 OK,
12231 kSecureServer,
12232 AUTH_SYNC,
12233 OK,
12234 3,
12235 1,
12236 {TestRound(kConnect, kProxyChallenge, OK),
12237 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12238 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512239 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112240 {__LINE__,
12241 kProxy,
asankac93076192016-10-03 15:46:0212242 AUTH_ASYNC,
12243 OK,
12244 kSecureServer,
12245 AUTH_SYNC,
12246 ERR_INVALID_AUTH_CREDENTIALS,
12247 3,
12248 1,
12249 {TestRound(kConnect, kProxyChallenge, OK),
12250 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12251 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612252 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112253 {__LINE__,
12254 kProxy,
asankac93076192016-10-03 15:46:0212255 AUTH_SYNC,
12256 OK,
12257 kSecureServer,
12258 AUTH_ASYNC,
12259 OK,
12260 3,
12261 1,
12262 {TestRound(kConnect, kProxyChallenge, OK),
12263 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12264 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512265 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112266 {__LINE__,
12267 kProxy,
asankac93076192016-10-03 15:46:0212268 AUTH_SYNC,
12269 OK,
12270 kSecureServer,
12271 AUTH_ASYNC,
12272 ERR_INVALID_AUTH_CREDENTIALS,
12273 3,
12274 1,
12275 {TestRound(kConnect, kProxyChallenge, OK),
12276 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12277 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612278 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112279 {__LINE__,
12280 kProxy,
asankac93076192016-10-03 15:46:0212281 AUTH_ASYNC,
12282 OK,
12283 kSecureServer,
12284 AUTH_ASYNC,
12285 OK,
12286 3,
12287 1,
12288 {TestRound(kConnect, kProxyChallenge, OK),
12289 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12290 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512291 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112292 {__LINE__,
12293 kProxy,
asankac93076192016-10-03 15:46:0212294 AUTH_ASYNC,
12295 OK,
12296 kSecureServer,
12297 AUTH_ASYNC,
12298 ERR_INVALID_AUTH_CREDENTIALS,
12299 3,
12300 1,
12301 {TestRound(kConnect, kProxyChallenge, OK),
12302 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12303 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612304 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112305 {__LINE__,
12306 kProxy,
12307 AUTH_ASYNC,
12308 ERR_INVALID_AUTH_CREDENTIALS,
12309 kSecureServer,
12310 AUTH_ASYNC,
12311 ERR_INVALID_AUTH_CREDENTIALS,
12312 4,
12313 2,
12314 {TestRound(kConnect, kProxyChallenge, OK),
12315 TestRound(kConnect, kProxyChallenge, OK),
12316 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12317 &kServerChallenge),
12318 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512319 };
12320
asanka463ca4262016-11-16 02:34:3112321 for (const auto& test_config : test_configs) {
12322 SCOPED_TRACE(::testing::Message() << "Test config at "
12323 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812324 HttpAuthHandlerMock::Factory* auth_factory(
12325 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712326 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912327 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612328
12329 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512330 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112331 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812332 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12333 std::string auth_challenge = "Mock realm=proxy";
12334 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412335 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12336 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812337 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012338 empty_ssl_info, origin,
12339 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812340 auth_handler->SetGenerateExpectation(
12341 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112342 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812343 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12344 }
[email protected]044de0642010-06-17 10:42:1512345 }
12346 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012347 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512348 std::string auth_challenge = "Mock realm=server";
12349 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412350 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12351 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512352 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012353 empty_ssl_info, origin,
12354 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512355 auth_handler->SetGenerateExpectation(
12356 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112357 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812358 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612359
12360 // The second handler always succeeds. It should only be used where there
12361 // are multiple auth sessions for server auth in the same network
12362 // transaction using the same auth scheme.
12363 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12364 base::MakeUnique<HttpAuthHandlerMock>();
12365 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12366 empty_ssl_info, origin,
12367 NetLogWithSource());
12368 second_handler->SetGenerateExpectation(true, OK);
12369 auth_factory->AddMockHandler(second_handler.release(),
12370 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512371 }
12372 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312373 session_deps_.proxy_service =
12374 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512375 } else {
rdsmith82957ad2015-09-16 19:42:0312376 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512377 }
12378
12379 HttpRequestInfo request;
12380 request.method = "GET";
12381 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512382
danakj1fd259a02016-04-16 03:17:0912383 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512384
rchcb68dc62015-05-21 04:45:3612385 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12386
12387 std::vector<std::vector<MockRead>> mock_reads(1);
12388 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512389 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212390 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512391 const TestRound& read_write_round = test_config.rounds[round];
12392
12393 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612394 mock_reads.back().push_back(read_write_round.read);
12395 mock_writes.back().push_back(read_write_round.write);
12396
12397 // kProxyChallenge uses Proxy-Connection: close which means that the
12398 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412399 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612400 mock_reads.push_back(std::vector<MockRead>());
12401 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512402 }
12403
rchcb68dc62015-05-21 04:45:3612404 if (read_write_round.extra_read) {
12405 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512406 }
rchcb68dc62015-05-21 04:45:3612407 if (read_write_round.extra_write) {
12408 mock_writes.back().push_back(*read_write_round.extra_write);
12409 }
[email protected]044de0642010-06-17 10:42:1512410
12411 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512412 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712413 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512414 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612415 }
[email protected]044de0642010-06-17 10:42:1512416
danakj1fd259a02016-04-16 03:17:0912417 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612418 for (size_t i = 0; i < mock_reads.size(); ++i) {
bnc87dcefc2017-05-25 12:47:5812419 data_providers.push_back(base::MakeUnique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412420 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812421 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612422 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212423 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612424 }
12425
mmenkecc2298e2015-12-07 18:20:1812426 // Transaction must be created after DataProviders, so it's destroyed before
12427 // they are as well.
12428 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12429
rchcb68dc62015-05-21 04:45:3612430 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212431 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612432 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512433 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112434 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512435 int rv;
12436 if (round == 0) {
tfarina42834112016-09-22 13:38:2012437 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512438 } else {
[email protected]49639fa2011-12-20 23:22:4112439 rv = trans.RestartWithAuth(
12440 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512441 }
12442 if (rv == ERR_IO_PENDING)
12443 rv = callback.WaitForResult();
12444
12445 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612446 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012447 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512448 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512449 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12450 continue;
12451 }
12452 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212453 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512454 } else {
wezca1070932016-05-26 20:30:5212455 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612456 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512457 }
12458 }
[email protected]e5ae96a2010-04-14 20:12:4512459 }
12460}
12461
bncd16676a2016-07-20 16:23:0112462TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412463 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412464 HttpAuthHandlerMock::Factory* auth_factory(
12465 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712466 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312467 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712468 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12469 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412470
12471 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12472 auth_handler->set_connection_based(true);
12473 std::string auth_challenge = "Mock realm=server";
12474 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412475 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12476 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912477 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412478 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012479 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812480 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412481
[email protected]c871bce92010-07-15 21:51:1412482 int rv = OK;
12483 const HttpResponseInfo* response = NULL;
12484 HttpRequestInfo request;
12485 request.method = "GET";
12486 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712487
danakj1fd259a02016-04-16 03:17:0912488 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012489
12490 // Use a TCP Socket Pool with only one connection per group. This is used
12491 // to validate that the TCP socket is not released to the pool between
12492 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212493 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812494 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012495 50, // Max sockets for pool
12496 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112497 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12498 NULL, session_deps_.net_log);
bnc87dcefc2017-05-25 12:47:5812499 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212500 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812501 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012502
bnc691fda62016-08-12 00:43:1612503 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112504 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412505
12506 const MockWrite kGet(
12507 "GET / HTTP/1.1\r\n"
12508 "Host: www.example.com\r\n"
12509 "Connection: keep-alive\r\n\r\n");
12510 const MockWrite kGetAuth(
12511 "GET / HTTP/1.1\r\n"
12512 "Host: www.example.com\r\n"
12513 "Connection: keep-alive\r\n"
12514 "Authorization: auth_token\r\n\r\n");
12515
12516 const MockRead kServerChallenge(
12517 "HTTP/1.1 401 Unauthorized\r\n"
12518 "WWW-Authenticate: Mock realm=server\r\n"
12519 "Content-Type: text/html; charset=iso-8859-1\r\n"
12520 "Content-Length: 14\r\n\r\n"
12521 "Unauthorized\r\n");
12522 const MockRead kSuccess(
12523 "HTTP/1.1 200 OK\r\n"
12524 "Content-Type: text/html; charset=iso-8859-1\r\n"
12525 "Content-Length: 3\r\n\r\n"
12526 "Yes");
12527
12528 MockWrite writes[] = {
12529 // First round
12530 kGet,
12531 // Second round
12532 kGetAuth,
12533 // Third round
12534 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012535 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012536 kGetAuth,
12537 // Competing request
12538 kGet,
[email protected]c871bce92010-07-15 21:51:1412539 };
12540 MockRead reads[] = {
12541 // First round
12542 kServerChallenge,
12543 // Second round
12544 kServerChallenge,
12545 // Third round
[email protected]eca50e122010-09-11 14:03:3012546 kServerChallenge,
12547 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412548 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012549 // Competing response
12550 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412551 };
12552 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12553 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712554 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412555
thestig9d3bb0c2015-01-24 00:49:5112556 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012557
12558 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412559 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012560 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412561 if (rv == ERR_IO_PENDING)
12562 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112563 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612564 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212565 ASSERT_TRUE(response);
12566 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812567 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112568 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12569 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412570
[email protected]7ef4cbbb2011-02-06 11:19:1012571 // In between rounds, another request comes in for the same domain.
12572 // It should not be able to grab the TCP socket that trans has already
12573 // claimed.
bnc691fda62016-08-12 00:43:1612574 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112575 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012576 rv = trans_compete.Start(&request, callback_compete.callback(),
12577 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112578 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012579 // callback_compete.WaitForResult at this point would stall forever,
12580 // since the HttpNetworkTransaction does not release the request back to
12581 // the pool until after authentication completes.
12582
12583 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412584 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612585 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412586 if (rv == ERR_IO_PENDING)
12587 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112588 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612589 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212590 ASSERT_TRUE(response);
12591 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812592 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112593 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12594 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412595
[email protected]7ef4cbbb2011-02-06 11:19:1012596 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412597 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612598 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412599 if (rv == ERR_IO_PENDING)
12600 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112601 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612602 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212603 ASSERT_TRUE(response);
12604 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812605 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112606 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12607 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012608
[email protected]7ef4cbbb2011-02-06 11:19:1012609 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012610 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612611 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012612 if (rv == ERR_IO_PENDING)
12613 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112614 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612615 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212616 ASSERT_TRUE(response);
12617 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812618 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012619
asanka463ca4262016-11-16 02:34:3112620 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12621 // auth handler should transition to a DONE state in concert with the remote
12622 // server. But that's not something we can test here with a mock handler.
12623 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12624 auth_handler->state());
12625
[email protected]7ef4cbbb2011-02-06 11:19:1012626 // Read the body since the fourth round was successful. This will also
12627 // release the socket back to the pool.
12628 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612629 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012630 if (rv == ERR_IO_PENDING)
12631 rv = callback.WaitForResult();
12632 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612633 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012634 EXPECT_EQ(0, rv);
12635 // There are still 0 idle sockets, since the trans_compete transaction
12636 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812637 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012638
12639 // The competing request can now finish. Wait for the headers and then
12640 // read the body.
12641 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112642 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612643 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012644 if (rv == ERR_IO_PENDING)
12645 rv = callback.WaitForResult();
12646 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612647 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012648 EXPECT_EQ(0, rv);
12649
12650 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812651 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412652}
12653
[email protected]65041fa2010-05-21 06:56:5312654// This tests the case that a request is issued via http instead of spdy after
12655// npn is negotiated.
bncd16676a2016-07-20 16:23:0112656TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312657 HttpRequestInfo request;
12658 request.method = "GET";
bncce36dca22015-04-21 22:11:2312659 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312660
12661 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312662 MockWrite(
12663 "GET / HTTP/1.1\r\n"
12664 "Host: www.example.org\r\n"
12665 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312666 };
12667
12668 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212669 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312670 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212671 MockRead("\r\n"),
12672 MockRead("hello world"),
12673 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312674 };
12675
[email protected]8ddf8322012-02-23 18:08:0612676 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612677 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312678
[email protected]bb88e1d32013-05-03 23:11:0712679 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312680
12681 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12682 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712683 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312684
[email protected]49639fa2011-12-20 23:22:4112685 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312686
danakj1fd259a02016-04-16 03:17:0912687 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312689
tfarina42834112016-09-22 13:38:2012690 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312691
robpercival214763f2016-07-01 23:27:0112692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12693 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312694
bnc691fda62016-08-12 00:43:1612695 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212696 ASSERT_TRUE(response);
12697 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312698 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12699
12700 std::string response_data;
bnc691fda62016-08-12 00:43:1612701 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312702 EXPECT_EQ("hello world", response_data);
12703
12704 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212705 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312706}
[email protected]26ef6582010-06-24 02:30:4712707
bnc55ff9da2015-08-19 18:42:3512708// Simulate the SSL handshake completing with an NPN negotiation followed by an
12709// immediate server closing of the socket.
12710// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112711TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712712 HttpRequestInfo request;
12713 request.method = "GET";
bncce36dca22015-04-21 22:11:2312714 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712715
[email protected]8ddf8322012-02-23 18:08:0612716 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612717 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712718 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712719
bncdf80d44fd2016-07-15 20:27:4112720 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912721 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112722 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712723
12724 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612725 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712726 };
12727
rch8e6c6c42015-05-01 14:05:1312728 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12729 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712730 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712731
[email protected]49639fa2011-12-20 23:22:4112732 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712733
danakj1fd259a02016-04-16 03:17:0912734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712736
tfarina42834112016-09-22 13:38:2012737 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12739 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712740}
[email protected]65d34382010-07-01 18:12:2612741
[email protected]795cbf82013-07-22 09:37:2712742// A subclass of HttpAuthHandlerMock that records the request URL when
12743// it gets it. This is needed since the auth handler may get destroyed
12744// before we get a chance to query it.
12745class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12746 public:
12747 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12748
dchengb03027d2014-10-21 12:00:2012749 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712750
12751 protected:
dchengb03027d2014-10-21 12:00:2012752 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12753 const HttpRequestInfo* request,
12754 const CompletionCallback& callback,
12755 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712756 *url_ = request->url;
12757 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12758 credentials, request, callback, auth_token);
12759 }
12760
12761 private:
12762 GURL* url_;
12763};
12764
[email protected]8e6441ca2010-08-19 05:56:3812765// Test that if we cancel the transaction as the connection is completing, that
12766// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112767TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812768 // Setup everything about the connection to complete synchronously, so that
12769 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12770 // for is the callback from the HttpStreamRequest.
12771 // Then cancel the transaction.
12772 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612773 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812774 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612775 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12776 MockRead(SYNCHRONOUS, "hello world"),
12777 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812778 };
12779
[email protected]8e6441ca2010-08-19 05:56:3812780 HttpRequestInfo request;
12781 request.method = "GET";
bncce36dca22015-04-21 22:11:2312782 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812783
[email protected]bb88e1d32013-05-03 23:11:0712784 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812786 auto trans =
12787 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2712788
[email protected]8e6441ca2010-08-19 05:56:3812789 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12790 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712791 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812792
[email protected]49639fa2011-12-20 23:22:4112793 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812794
vishal.b62985ca92015-04-17 08:45:5112795 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112796 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812798 trans.reset(); // Cancel the transaction here.
12799
fdoray92e35a72016-06-10 15:54:5512800 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012801}
12802
[email protected]ecab6e052014-05-16 14:58:1212803// Test that if a transaction is cancelled after receiving the headers, the
12804// stream is drained properly and added back to the socket pool. The main
12805// purpose of this test is to make sure that an HttpStreamParser can be read
12806// from after the HttpNetworkTransaction and the objects it owns have been
12807// deleted.
12808// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112809TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212810 MockRead data_reads[] = {
12811 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12812 MockRead(ASYNC, "Content-Length: 2\r\n"),
12813 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12814 MockRead(ASYNC, "1"),
12815 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12816 // HttpNetworkTransaction has been deleted.
12817 MockRead(ASYNC, "2"),
12818 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12819 };
12820 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12821 session_deps_.socket_factory->AddSocketDataProvider(&data);
12822
danakj1fd259a02016-04-16 03:17:0912823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212824
12825 {
12826 HttpRequestInfo request;
12827 request.method = "GET";
bncce36dca22015-04-21 22:11:2312828 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212829
dcheng48459ac22014-08-26 00:46:4112830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212831 TestCompletionCallback callback;
12832
tfarina42834112016-09-22 13:38:2012833 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212835 callback.WaitForResult();
12836
12837 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212838 ASSERT_TRUE(response);
12839 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212840 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12841
12842 // The transaction and HttpRequestInfo are deleted.
12843 }
12844
12845 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512846 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212847
12848 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112849 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212850}
12851
[email protected]76a505b2010-08-25 06:23:0012852// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112853TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312854 session_deps_.proxy_service =
12855 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112856 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712857 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012859
[email protected]76a505b2010-08-25 06:23:0012860 HttpRequestInfo request;
12861 request.method = "GET";
bncce36dca22015-04-21 22:11:2312862 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012863
12864 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312865 MockWrite(
12866 "GET http://www.example.org/ HTTP/1.1\r\n"
12867 "Host: www.example.org\r\n"
12868 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012869 };
12870
12871 MockRead data_reads1[] = {
12872 MockRead("HTTP/1.1 200 OK\r\n"),
12873 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12874 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612875 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012876 };
12877
12878 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12879 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712880 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012881
[email protected]49639fa2011-12-20 23:22:4112882 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012883
bnc691fda62016-08-12 00:43:1612884 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912885 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612886 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912887 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12888 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012889
bnc691fda62016-08-12 00:43:1612890 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012892
12893 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112894 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012895
bnc691fda62016-08-12 00:43:1612896 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212897 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012898
12899 EXPECT_TRUE(response->headers->IsKeepAlive());
12900 EXPECT_EQ(200, response->headers->response_code());
12901 EXPECT_EQ(100, response->headers->GetContentLength());
12902 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712903 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12904 HostPortPair::FromString("myproxy:70")),
12905 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912906 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12907 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12908 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012909 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012910
12911 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612912 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012913 TestLoadTimingNotReusedWithPac(load_timing_info,
12914 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012915}
12916
12917// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112918TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312919 session_deps_.proxy_service =
12920 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112921 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712922 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012924
[email protected]76a505b2010-08-25 06:23:0012925 HttpRequestInfo request;
12926 request.method = "GET";
bncce36dca22015-04-21 22:11:2312927 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012928
12929 // Since we have proxy, should try to establish tunnel.
12930 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712931 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12932 "Host: www.example.org:443\r\n"
12933 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012934
rsleevidb16bb02015-11-12 23:47:1712935 MockWrite("GET / HTTP/1.1\r\n"
12936 "Host: www.example.org\r\n"
12937 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012938 };
12939
12940 MockRead data_reads1[] = {
12941 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12942
12943 MockRead("HTTP/1.1 200 OK\r\n"),
12944 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12945 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612946 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012947 };
12948
12949 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12950 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712951 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612952 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712953 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012954
[email protected]49639fa2011-12-20 23:22:4112955 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012956
bnc691fda62016-08-12 00:43:1612957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912958 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612959 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912960 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12961 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012962
bnc691fda62016-08-12 00:43:1612963 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012965
12966 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112967 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612968 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012969 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012970 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012971 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12972 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012973 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012974 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012975 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12976 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012977
bnc691fda62016-08-12 00:43:1612978 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212979 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012980
12981 EXPECT_TRUE(response->headers->IsKeepAlive());
12982 EXPECT_EQ(200, response->headers->response_code());
12983 EXPECT_EQ(100, response->headers->GetContentLength());
12984 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12985 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712986 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12987 HostPortPair::FromString("myproxy:70")),
12988 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912989 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12990 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12991 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012992
12993 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612994 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012995 TestLoadTimingNotReusedWithPac(load_timing_info,
12996 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012997}
12998
rsleevidb16bb02015-11-12 23:47:1712999// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13000// literal host.
bncd16676a2016-07-20 16:23:0113001TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1713002 session_deps_.proxy_service =
13003 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
13004 BoundTestNetLog log;
13005 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713007
13008 HttpRequestInfo request;
13009 request.method = "GET";
13010 request.url = GURL("https://[::1]:443/");
13011
13012 // Since we have proxy, should try to establish tunnel.
13013 MockWrite data_writes1[] = {
13014 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13015 "Host: [::1]:443\r\n"
13016 "Proxy-Connection: keep-alive\r\n\r\n"),
13017
13018 MockWrite("GET / HTTP/1.1\r\n"
13019 "Host: [::1]\r\n"
13020 "Connection: keep-alive\r\n\r\n"),
13021 };
13022
13023 MockRead data_reads1[] = {
13024 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13025
13026 MockRead("HTTP/1.1 200 OK\r\n"),
13027 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13028 MockRead("Content-Length: 100\r\n\r\n"),
13029 MockRead(SYNCHRONOUS, OK),
13030 };
13031
13032 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13033 data_writes1, arraysize(data_writes1));
13034 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13035 SSLSocketDataProvider ssl(ASYNC, OK);
13036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13037
13038 TestCompletionCallback callback1;
13039
bnc691fda62016-08-12 00:43:1613040 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713041
bnc691fda62016-08-12 00:43:1613042 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113043 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713044
13045 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113046 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713047 TestNetLogEntry::List entries;
13048 log.GetEntries(&entries);
13049 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013050 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13051 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713052 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013053 entries, pos,
13054 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13055 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713056
bnc691fda62016-08-12 00:43:1613057 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213058 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713059
13060 EXPECT_TRUE(response->headers->IsKeepAlive());
13061 EXPECT_EQ(200, response->headers->response_code());
13062 EXPECT_EQ(100, response->headers->GetContentLength());
13063 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13064 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713065 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13066 HostPortPair::FromString("myproxy:70")),
13067 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713068
13069 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613070 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713071 TestLoadTimingNotReusedWithPac(load_timing_info,
13072 CONNECT_TIMING_HAS_SSL_TIMES);
13073}
13074
[email protected]76a505b2010-08-25 06:23:0013075// Test a basic HTTPS GET request through a proxy, but the server hangs up
13076// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113077TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0313078 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113079 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713080 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913081 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013082
[email protected]76a505b2010-08-25 06:23:0013083 HttpRequestInfo request;
13084 request.method = "GET";
bncce36dca22015-04-21 22:11:2313085 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013086
13087 // Since we have proxy, should try to establish tunnel.
13088 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713089 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13090 "Host: www.example.org:443\r\n"
13091 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013092
rsleevidb16bb02015-11-12 23:47:1713093 MockWrite("GET / HTTP/1.1\r\n"
13094 "Host: www.example.org\r\n"
13095 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013096 };
13097
13098 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613099 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013100 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613101 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013102 };
13103
13104 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13105 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713106 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613107 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713108 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013109
[email protected]49639fa2011-12-20 23:22:4113110 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013111
bnc691fda62016-08-12 00:43:1613112 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013113
bnc691fda62016-08-12 00:43:1613114 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113115 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013116
13117 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113118 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613119 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013120 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013121 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013122 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13123 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013124 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013125 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013126 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13127 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013128}
13129
[email protected]749eefa82010-09-13 22:14:0313130// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113131TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113132 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913133 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113134 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313135
bnc42331402016-07-25 13:36:1513136 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113137 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313138 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113139 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313140 };
13141
rch8e6c6c42015-05-01 14:05:1313142 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13143 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713144 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313145
[email protected]8ddf8322012-02-23 18:08:0613146 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613147 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713148 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313149
danakj1fd259a02016-04-16 03:17:0913150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313151
13152 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313153 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013154 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313155 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713156 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213157 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313158
13159 HttpRequestInfo request;
13160 request.method = "GET";
bncce36dca22015-04-21 22:11:2313161 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313162
13163 // This is the important line that marks this as a preconnect.
13164 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13165
bnc691fda62016-08-12 00:43:1613166 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313167
[email protected]41d64e82013-07-03 22:44:2613168 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013169 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13171 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313172}
13173
[email protected]73b8dd222010-11-11 19:55:2413174// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613175// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213176void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713177 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913178 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713179 request_info.url = GURL("https://www.example.com/");
13180 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913181 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713182
[email protected]8ddf8322012-02-23 18:08:0613183 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913184 MockWrite data_writes[] = {
13185 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413186 };
ttuttle859dc7a2015-04-23 19:42:2913187 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713188 session_deps_.socket_factory->AddSocketDataProvider(&data);
13189 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413190
danakj1fd259a02016-04-16 03:17:0913191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413193
[email protected]49639fa2011-12-20 23:22:4113194 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013195 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913196 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413197 rv = callback.WaitForResult();
13198 ASSERT_EQ(error, rv);
13199}
13200
bncd16676a2016-07-20 16:23:0113201TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413202 // Just check a grab bag of cert errors.
13203 static const int kErrors[] = {
13204 ERR_CERT_COMMON_NAME_INVALID,
13205 ERR_CERT_AUTHORITY_INVALID,
13206 ERR_CERT_DATE_INVALID,
13207 };
13208 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613209 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13210 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413211 }
13212}
13213
[email protected]bd0b6772011-01-11 19:59:3013214// Ensure that a client certificate is removed from the SSL client auth
13215// cache when:
13216// 1) No proxy is involved.
13217// 2) TLS False Start is disabled.
13218// 3) The initial TLS handshake requests a client certificate.
13219// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113220TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913221 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713222 request_info.url = GURL("https://www.example.com/");
13223 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913224 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713225
[email protected]bd0b6772011-01-11 19:59:3013226 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113227 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013228
13229 // [ssl_]data1 contains the data for the first SSL handshake. When a
13230 // CertificateRequest is received for the first time, the handshake will
13231 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913232 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013233 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913235 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713236 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013237
13238 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13239 // False Start is not being used, the result of the SSL handshake will be
13240 // returned as part of the SSLClientSocket::Connect() call. This test
13241 // matches the result of a server sending a handshake_failure alert,
13242 // rather than a Finished message, because it requires a client
13243 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913244 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013245 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913247 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713248 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013249
13250 // [ssl_]data3 contains the data for the third SSL handshake. When a
13251 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213252 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13253 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013254 // of the HttpNetworkTransaction. Because this test failure is due to
13255 // requiring a client certificate, this fallback handshake should also
13256 // fail.
ttuttle859dc7a2015-04-23 19:42:2913257 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013258 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713259 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913260 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713261 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013262
[email protected]80c75f682012-05-26 16:22:1713263 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13264 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213265 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13266 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713267 // of the HttpNetworkTransaction. Because this test failure is due to
13268 // requiring a client certificate, this fallback handshake should also
13269 // fail.
ttuttle859dc7a2015-04-23 19:42:2913270 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713271 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713272 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913273 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713274 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713275
danakj1fd259a02016-04-16 03:17:0913276 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613277 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013278
[email protected]bd0b6772011-01-11 19:59:3013279 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113280 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013281 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113282 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013283
13284 // Complete the SSL handshake, which should abort due to requiring a
13285 // client certificate.
13286 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113287 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013288
13289 // Indicate that no certificate should be supplied. From the perspective
13290 // of SSLClientCertCache, NULL is just as meaningful as a real
13291 // certificate, so this is the same as supply a
13292 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613293 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113294 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013295
13296 // Ensure the certificate was added to the client auth cache before
13297 // allowing the connection to continue restarting.
13298 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413299 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113300 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413301 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213302 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013303
13304 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713305 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13306 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013307 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113308 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013309
13310 // Ensure that the client certificate is removed from the cache on a
13311 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113312 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413313 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013314}
13315
13316// Ensure that a client certificate is removed from the SSL client auth
13317// cache when:
13318// 1) No proxy is involved.
13319// 2) TLS False Start is enabled.
13320// 3) The initial TLS handshake requests a client certificate.
13321// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113322TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913323 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713324 request_info.url = GURL("https://www.example.com/");
13325 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913326 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713327
[email protected]bd0b6772011-01-11 19:59:3013328 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113329 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013330
13331 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13332 // return successfully after reading up to the peer's Certificate message.
13333 // This is to allow the caller to call SSLClientSocket::Write(), which can
13334 // enqueue application data to be sent in the same packet as the
13335 // ChangeCipherSpec and Finished messages.
13336 // The actual handshake will be finished when SSLClientSocket::Read() is
13337 // called, which expects to process the peer's ChangeCipherSpec and
13338 // Finished messages. If there was an error negotiating with the peer,
13339 // such as due to the peer requiring a client certificate when none was
13340 // supplied, the alert sent by the peer won't be processed until Read() is
13341 // called.
13342
13343 // Like the non-False Start case, when a client certificate is requested by
13344 // the peer, the handshake is aborted during the Connect() call.
13345 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913346 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013347 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913349 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713350 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013351
13352 // When a client certificate is supplied, Connect() will not be aborted
13353 // when the peer requests the certificate. Instead, the handshake will
13354 // artificially succeed, allowing the caller to write the HTTP request to
13355 // the socket. The handshake messages are not processed until Read() is
13356 // called, which then detects that the handshake was aborted, due to the
13357 // peer sending a handshake_failure because it requires a client
13358 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913359 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013360 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913362 MockRead data2_reads[] = {
13363 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013364 };
ttuttle859dc7a2015-04-23 19:42:2913365 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713366 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013367
13368 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713369 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13370 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913371 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013372 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913374 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713375 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013376
[email protected]80c75f682012-05-26 16:22:1713377 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13378 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913379 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713380 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913382 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713383 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713384
[email protected]7799de12013-05-30 05:52:5113385 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913386 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113387 ssl_data5.cert_request_info = cert_request.get();
13388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913389 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113390 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13391
danakj1fd259a02016-04-16 03:17:0913392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013394
[email protected]bd0b6772011-01-11 19:59:3013395 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113396 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013397 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113398 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013399
13400 // Complete the SSL handshake, which should abort due to requiring a
13401 // client certificate.
13402 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113403 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013404
13405 // Indicate that no certificate should be supplied. From the perspective
13406 // of SSLClientCertCache, NULL is just as meaningful as a real
13407 // certificate, so this is the same as supply a
13408 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613409 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113410 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013411
13412 // Ensure the certificate was added to the client auth cache before
13413 // allowing the connection to continue restarting.
13414 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413415 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113416 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413417 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213418 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013419
[email protected]bd0b6772011-01-11 19:59:3013420 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713421 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13422 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013423 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113424 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013425
13426 // Ensure that the client certificate is removed from the cache on a
13427 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113428 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413429 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013430}
13431
[email protected]8c405132011-01-11 22:03:1813432// Ensure that a client certificate is removed from the SSL client auth
13433// cache when:
13434// 1) An HTTPS proxy is involved.
13435// 3) The HTTPS proxy requests a client certificate.
13436// 4) The client supplies an invalid/unacceptable certificate for the
13437// proxy.
13438// The test is repeated twice, first for connecting to an HTTPS endpoint,
13439// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113440TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313441 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113442 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713443 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813444
13445 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113446 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813447
13448 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13449 // [ssl_]data[1-3]. Rather than represending the endpoint
13450 // (www.example.com:443), they represent failures with the HTTPS proxy
13451 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913452 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813453 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913455 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713456 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813457
ttuttle859dc7a2015-04-23 19:42:2913458 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813459 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713460 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913461 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713462 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813463
[email protected]80c75f682012-05-26 16:22:1713464 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13465#if 0
ttuttle859dc7a2015-04-23 19:42:2913466 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813467 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913469 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713470 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713471#endif
[email protected]8c405132011-01-11 22:03:1813472
ttuttle859dc7a2015-04-23 19:42:2913473 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813474 requests[0].url = GURL("https://www.example.com/");
13475 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913476 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813477
13478 requests[1].url = GURL("http://www.example.com/");
13479 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913480 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813481
13482 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713483 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813486
13487 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113488 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013489 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113490 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813491
13492 // Complete the SSL handshake, which should abort due to requiring a
13493 // client certificate.
13494 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113495 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813496
13497 // Indicate that no certificate should be supplied. From the perspective
13498 // of SSLClientCertCache, NULL is just as meaningful as a real
13499 // certificate, so this is the same as supply a
13500 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613501 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113502 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813503
13504 // Ensure the certificate was added to the client auth cache before
13505 // allowing the connection to continue restarting.
13506 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413507 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113508 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413509 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213510 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813511 // Ensure the certificate was NOT cached for the endpoint. This only
13512 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113513 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413514 HostPortPair("www.example.com", 443), &client_cert,
13515 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813516
13517 // Restart the handshake. This will consume ssl_data2, which fails, and
13518 // then consume ssl_data3, which should also fail. The result code is
13519 // checked against what ssl_data3 should return.
13520 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113521 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813522
13523 // Now that the new handshake has failed, ensure that the client
13524 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113525 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413526 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113527 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413528 HostPortPair("www.example.com", 443), &client_cert,
13529 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813530 }
13531}
13532
bncd16676a2016-07-20 16:23:0113533TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613534 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813535 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913536 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613537
bnc032658ba2016-09-26 18:17:1513538 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613539
bncdf80d44fd2016-07-15 20:27:4113540 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913541 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813542 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113543 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713544 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613545 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113546 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613547 };
bnc42331402016-07-25 13:36:1513548 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113549 SpdySerializedFrame host1_resp_body(
13550 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513551 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113552 SpdySerializedFrame host2_resp_body(
13553 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613554 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113555 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13556 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313557 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613558 };
13559
eroman36d84e54432016-03-17 03:23:0213560 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213561 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313562 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13563 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713564 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613565
[email protected]aa22b242011-11-16 18:58:2913566 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613567 HttpRequestInfo request1;
13568 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313569 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613570 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013571 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613572
tfarina42834112016-09-22 13:38:2013573 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13575 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613576
13577 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213578 ASSERT_TRUE(response);
13579 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213580 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613581
13582 std::string response_data;
robpercival214763f2016-07-01 23:27:0113583 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613584 EXPECT_EQ("hello!", response_data);
13585
bnca4d611d2016-09-22 19:55:3713586 // Preload mail.example.com into HostCache.
13587 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013588 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613589 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013590 std::unique_ptr<HostResolver::Request> request;
13591 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13592 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013593 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713595 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113596 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613597
13598 HttpRequestInfo request2;
13599 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713600 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613601 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013602 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613603
tfarina42834112016-09-22 13:38:2013604 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13606 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613607
13608 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213609 ASSERT_TRUE(response);
13610 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213611 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613612 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213613 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113614 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613615 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613616}
13617
bncd16676a2016-07-20 16:23:0113618TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213619 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813620 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213622
bnc032658ba2016-09-26 18:17:1513623 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213624
bncdf80d44fd2016-07-15 20:27:4113625 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913626 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813627 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113628 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713629 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213630 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113631 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213632 };
bnc42331402016-07-25 13:36:1513633 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113634 SpdySerializedFrame host1_resp_body(
13635 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513636 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113637 SpdySerializedFrame host2_resp_body(
13638 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213639 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113640 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13641 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313642 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213643 };
13644
eroman36d84e54432016-03-17 03:23:0213645 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213646 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313647 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13648 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713649 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213650
13651 TestCompletionCallback callback;
13652 HttpRequestInfo request1;
13653 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313654 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213655 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013656 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213657
tfarina42834112016-09-22 13:38:2013658 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13660 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213661
13662 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213663 ASSERT_TRUE(response);
13664 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213665 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213666
13667 std::string response_data;
robpercival214763f2016-07-01 23:27:0113668 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213669 EXPECT_EQ("hello!", response_data);
13670
13671 HttpRequestInfo request2;
13672 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713673 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213674 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013675 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213676
tfarina42834112016-09-22 13:38:2013677 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13679 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213680
13681 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213682 ASSERT_TRUE(response);
13683 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213684 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213685 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213686 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113687 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213688 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213689}
13690
bnc8016c1f2017-03-31 02:11:2913691// Regression test for https://crbug.com/546991.
13692// The server might not be able to serve an IP pooled request, and might send a
13693// 421 Misdirected Request response status to indicate this.
13694// HttpNetworkTransaction should reset the request and retry without IP pooling.
13695TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13696 // Two hosts resolve to the same IP address.
13697 const std::string ip_addr = "1.2.3.4";
13698 IPAddress ip;
13699 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13700 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13701
bnc87dcefc2017-05-25 12:47:5813702 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913703 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13704 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13705
13706 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13707
13708 // Two requests on the first connection.
13709 SpdySerializedFrame req1(
13710 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13711 spdy_util_.UpdateWithStreamDestruction(1);
13712 SpdySerializedFrame req2(
13713 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13714 SpdySerializedFrame rst(
13715 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13716 MockWrite writes1[] = {
13717 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13718 CreateMockWrite(rst, 6),
13719 };
13720
13721 // The first one succeeds, the second gets error 421 Misdirected Request.
13722 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13723 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13724 SpdyHeaderBlock response_headers;
13725 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13726 SpdySerializedFrame resp2(
13727 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13728 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13729 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13730
13731 MockConnect connect1(ASYNC, OK, peer_addr);
13732 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13733 arraysize(writes1));
13734 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13735
13736 AddSSLSocketData();
13737
13738 // Retry the second request on a second connection.
13739 SpdyTestUtil spdy_util2;
13740 SpdySerializedFrame req3(
13741 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13742 MockWrite writes2[] = {
13743 CreateMockWrite(req3, 0),
13744 };
13745
13746 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13747 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13748 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13749 MockRead(ASYNC, 0, 3)};
13750
13751 MockConnect connect2(ASYNC, OK, peer_addr);
13752 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13753 arraysize(writes2));
13754 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13755
13756 AddSSLSocketData();
13757
13758 // Preload mail.example.org into HostCache.
13759 HostPortPair host_port("mail.example.org", 443);
13760 HostResolver::RequestInfo resolve_info(host_port);
13761 AddressList ignored;
13762 std::unique_ptr<HostResolver::Request> request;
13763 TestCompletionCallback callback;
13764 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13765 &ignored, callback.callback(),
13766 &request, NetLogWithSource());
13767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13768 rv = callback.WaitForResult();
13769 EXPECT_THAT(rv, IsOk());
13770
13771 HttpRequestInfo request1;
13772 request1.method = "GET";
13773 request1.url = GURL("https://www.example.org/");
13774 request1.load_flags = 0;
13775 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13776
13777 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13779 rv = callback.WaitForResult();
13780 EXPECT_THAT(rv, IsOk());
13781
13782 const HttpResponseInfo* response = trans1.GetResponseInfo();
13783 ASSERT_TRUE(response);
13784 ASSERT_TRUE(response->headers);
13785 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13786 EXPECT_TRUE(response->was_fetched_via_spdy);
13787 EXPECT_TRUE(response->was_alpn_negotiated);
13788 std::string response_data;
13789 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13790 EXPECT_EQ("hello!", response_data);
13791
13792 HttpRequestInfo request2;
13793 request2.method = "GET";
13794 request2.url = GURL("https://mail.example.org/");
13795 request2.load_flags = 0;
13796 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13797
13798 BoundTestNetLog log;
13799 rv = trans2.Start(&request2, callback.callback(), log.bound());
13800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13801 rv = callback.WaitForResult();
13802 EXPECT_THAT(rv, IsOk());
13803
13804 response = trans2.GetResponseInfo();
13805 ASSERT_TRUE(response);
13806 ASSERT_TRUE(response->headers);
13807 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13808 EXPECT_TRUE(response->was_fetched_via_spdy);
13809 EXPECT_TRUE(response->was_alpn_negotiated);
13810 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13811 EXPECT_EQ("hello!", response_data);
13812
13813 TestNetLogEntry::List entries;
13814 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5913815 ExpectLogContainsSomewhere(
13816 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2913817 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5913818}
13819
13820// Test that HTTP 421 responses are properly returned to the caller if received
13821// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
13822// portions of the response.
13823TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
13824 // Two hosts resolve to the same IP address.
13825 const std::string ip_addr = "1.2.3.4";
13826 IPAddress ip;
13827 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13828 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13829
bnc87dcefc2017-05-25 12:47:5813830 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5913831 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13832 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13833
13834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13835
13836 // Two requests on the first connection.
13837 SpdySerializedFrame req1(
13838 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13839 spdy_util_.UpdateWithStreamDestruction(1);
13840 SpdySerializedFrame req2(
13841 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13842 SpdySerializedFrame rst(
13843 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13844 MockWrite writes1[] = {
13845 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13846 CreateMockWrite(rst, 6),
13847 };
13848
13849 // The first one succeeds, the second gets error 421 Misdirected Request.
13850 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13851 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13852 SpdyHeaderBlock response_headers;
13853 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13854 SpdySerializedFrame resp2(
13855 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
13856 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13857 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13858
13859 MockConnect connect1(ASYNC, OK, peer_addr);
13860 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13861 arraysize(writes1));
13862 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13863
13864 AddSSLSocketData();
13865
13866 // Retry the second request on a second connection. It returns 421 Misdirected
13867 // Retry again.
13868 SpdyTestUtil spdy_util2;
13869 SpdySerializedFrame req3(
13870 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13871 MockWrite writes2[] = {
13872 CreateMockWrite(req3, 0),
13873 };
13874
13875 SpdySerializedFrame resp3(
13876 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
13877 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13878 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13879 MockRead(ASYNC, 0, 3)};
13880
13881 MockConnect connect2(ASYNC, OK, peer_addr);
13882 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13883 arraysize(writes2));
13884 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13885
13886 AddSSLSocketData();
13887
13888 // Preload mail.example.org into HostCache.
13889 HostPortPair host_port("mail.example.org", 443);
13890 HostResolver::RequestInfo resolve_info(host_port);
13891 AddressList ignored;
13892 std::unique_ptr<HostResolver::Request> request;
13893 TestCompletionCallback callback;
13894 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13895 &ignored, callback.callback(),
13896 &request, NetLogWithSource());
13897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13898 rv = callback.WaitForResult();
13899 EXPECT_THAT(rv, IsOk());
13900
13901 HttpRequestInfo request1;
13902 request1.method = "GET";
13903 request1.url = GURL("https://www.example.org/");
13904 request1.load_flags = 0;
13905 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13906
13907 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13909 rv = callback.WaitForResult();
13910 EXPECT_THAT(rv, IsOk());
13911
13912 const HttpResponseInfo* response = trans1.GetResponseInfo();
13913 ASSERT_TRUE(response);
13914 ASSERT_TRUE(response->headers);
13915 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13916 EXPECT_TRUE(response->was_fetched_via_spdy);
13917 EXPECT_TRUE(response->was_alpn_negotiated);
13918 std::string response_data;
13919 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13920 EXPECT_EQ("hello!", response_data);
13921
13922 HttpRequestInfo request2;
13923 request2.method = "GET";
13924 request2.url = GURL("https://mail.example.org/");
13925 request2.load_flags = 0;
13926 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13927
13928 BoundTestNetLog log;
13929 rv = trans2.Start(&request2, callback.callback(), log.bound());
13930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13931 rv = callback.WaitForResult();
13932 EXPECT_THAT(rv, IsOk());
13933
13934 // After a retry, the 421 Misdirected Request is reported back up to the
13935 // caller.
13936 response = trans2.GetResponseInfo();
13937 ASSERT_TRUE(response);
13938 ASSERT_TRUE(response->headers);
13939 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
13940 EXPECT_TRUE(response->was_fetched_via_spdy);
13941 EXPECT_TRUE(response->was_alpn_negotiated);
13942 EXPECT_TRUE(response->ssl_info.cert);
13943 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13944 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2913945}
13946
bnc6dcd8192017-05-25 20:11:5013947class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4613948 public:
13949 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5013950 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013951 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613952
dchengb03027d2014-10-21 12:00:2013953 int ResolveFromCache(const RequestInfo& info,
13954 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013955 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5013956 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4013957 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5013958 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613959 return rv;
13960 }
13961
[email protected]e3ceb682011-06-28 23:55:4613962 private:
[email protected]e3ceb682011-06-28 23:55:4613963 const HostPortPair host_port_;
13964};
13965
bncd16676a2016-07-20 16:23:0113966TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313967 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613968 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnc6dcd8192017-05-25 20:11:5013969 session_deps_.host_resolver = base::MakeUnique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3713970 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0913971 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613972
bnc032658ba2016-09-26 18:17:1513973 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613974
bncdf80d44fd2016-07-15 20:27:4113975 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913976 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813977 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113978 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713979 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613980 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113981 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613982 };
bnc42331402016-07-25 13:36:1513983 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113984 SpdySerializedFrame host1_resp_body(
13985 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513986 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113987 SpdySerializedFrame host2_resp_body(
13988 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613989 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113990 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13991 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313992 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613993 };
13994
eroman36d84e54432016-03-17 03:23:0213995 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213996 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313997 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13998 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713999 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614000
[email protected]aa22b242011-11-16 18:58:2914001 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614002 HttpRequestInfo request1;
14003 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314004 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614005 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014006 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614007
tfarina42834112016-09-22 13:38:2014008 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14010 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614011
14012 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214013 ASSERT_TRUE(response);
14014 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214015 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614016
14017 std::string response_data;
robpercival214763f2016-07-01 23:27:0114018 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614019 EXPECT_EQ("hello!", response_data);
14020
14021 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714022 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614023 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014024 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014025 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14026 &ignored, callback.callback(),
14027 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114028 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714029 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114030 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614031
14032 HttpRequestInfo request2;
14033 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714034 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614035 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014036 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614037
tfarina42834112016-09-22 13:38:2014038 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14040 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614041
14042 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214043 ASSERT_TRUE(response);
14044 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214045 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614046 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214047 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114048 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614049 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614050}
14051
bncd16676a2016-07-20 16:23:0114052TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314053 const std::string https_url = "https://www.example.org:8080/";
14054 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414055
14056 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114057 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914058 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414059
14060 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114061 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414062 };
14063
bnc42331402016-07-25 13:36:1514064 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114065 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14066 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914067 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414068
rch8e6c6c42015-05-01 14:05:1314069 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14070 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414071 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714072 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414073
14074 // HTTP GET for the HTTP URL
14075 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314076 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414077 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314078 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414079 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414080 };
14081
14082 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314083 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14084 MockRead(ASYNC, 2, "hello"),
14085 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414086 };
14087
rch8e6c6c42015-05-01 14:05:1314088 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14089 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414090
[email protected]8450d722012-07-02 19:14:0414091 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614092 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14094 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14095 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414096
danakj1fd259a02016-04-16 03:17:0914097 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414098
14099 // Start the first transaction to set up the SpdySession
14100 HttpRequestInfo request1;
14101 request1.method = "GET";
14102 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414103 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014104 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414105 TestCompletionCallback callback1;
14106 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014107 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514108 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414109
robpercival214763f2016-07-01 23:27:0114110 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414111 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14112
14113 // Now, start the HTTP request
14114 HttpRequestInfo request2;
14115 request2.method = "GET";
14116 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414117 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014118 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414119 TestCompletionCallback callback2;
14120 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014121 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514122 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414123
robpercival214763f2016-07-01 23:27:0114124 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414125 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14126}
14127
bnc5452e2a2015-05-08 16:27:4214128// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14129// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114130TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514131 url::SchemeHostPort server("https", "www.example.org", 443);
14132 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214133
bnc8bef8da22016-05-30 01:28:2514134 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214135 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614136 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14138
14139 // No data should be read from the alternative, because HTTP/1.1 is
14140 // negotiated.
14141 StaticSocketDataProvider data;
14142 session_deps_.socket_factory->AddSocketDataProvider(&data);
14143
14144 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614145 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214146 // mocked. This way the request relies on the alternate Job.
14147 StaticSocketDataProvider data_refused;
14148 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14149 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14150
zhongyi3d4a55e72016-04-22 20:36:4614151 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914152 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014153 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214154 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114155 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214156 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114157 http_server_properties->SetHttp2AlternativeService(
14158 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214159
bnc5452e2a2015-05-08 16:27:4214160 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614161 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214162 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514163 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214164 TestCompletionCallback callback;
14165
14166 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214167 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014168 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214169 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214170}
14171
bnc40448a532015-05-11 19:13:1414172// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614173// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414174// succeeds, the request should succeed, even if the latter fails because
14175// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114176TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514177 url::SchemeHostPort server("https", "www.example.org", 443);
14178 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414179
14180 // Negotiate HTTP/1.1 with alternative.
14181 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614182 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414183 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14184
14185 // No data should be read from the alternative, because HTTP/1.1 is
14186 // negotiated.
14187 StaticSocketDataProvider data;
14188 session_deps_.socket_factory->AddSocketDataProvider(&data);
14189
zhongyi3d4a55e72016-04-22 20:36:4614190 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414191 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614192 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414193 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14194
14195 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514196 MockWrite("GET / HTTP/1.1\r\n"
14197 "Host: www.example.org\r\n"
14198 "Connection: keep-alive\r\n\r\n"),
14199 MockWrite("GET /second HTTP/1.1\r\n"
14200 "Host: www.example.org\r\n"
14201 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414202 };
14203
14204 MockRead http_reads[] = {
14205 MockRead("HTTP/1.1 200 OK\r\n"),
14206 MockRead("Content-Type: text/html\r\n"),
14207 MockRead("Content-Length: 6\r\n\r\n"),
14208 MockRead("foobar"),
14209 MockRead("HTTP/1.1 200 OK\r\n"),
14210 MockRead("Content-Type: text/html\r\n"),
14211 MockRead("Content-Length: 7\r\n\r\n"),
14212 MockRead("another"),
14213 };
14214 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14215 http_writes, arraysize(http_writes));
14216 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14217
zhongyi3d4a55e72016-04-22 20:36:4614218 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914219 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014220 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414221 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114222 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214223 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114224 http_server_properties->SetHttp2AlternativeService(
14225 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414226
14227 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14228 HttpRequestInfo request1;
14229 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514230 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414231 request1.load_flags = 0;
14232 TestCompletionCallback callback1;
14233
tfarina42834112016-09-22 13:38:2014234 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414235 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114236 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414237
14238 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214239 ASSERT_TRUE(response1);
14240 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414241 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14242
14243 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114244 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414245 EXPECT_EQ("foobar", response_data1);
14246
14247 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14248 // for alternative service.
14249 EXPECT_TRUE(
14250 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14251
zhongyi3d4a55e72016-04-22 20:36:4614252 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414253 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614254 // to server.
bnc40448a532015-05-11 19:13:1414255 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14256 HttpRequestInfo request2;
14257 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514258 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414259 request2.load_flags = 0;
14260 TestCompletionCallback callback2;
14261
tfarina42834112016-09-22 13:38:2014262 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414263 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114264 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414265
14266 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214267 ASSERT_TRUE(response2);
14268 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414269 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14270
14271 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114272 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414273 EXPECT_EQ("another", response_data2);
14274}
14275
bnc5452e2a2015-05-08 16:27:4214276// Alternative service requires HTTP/2 (or SPDY), but there is already a
14277// HTTP/1.1 socket open to the alternative server. That socket should not be
14278// used.
bncd16676a2016-07-20 16:23:0114279TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614280 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214281 HostPortPair alternative("alternative.example.org", 443);
14282 std::string origin_url = "https://origin.example.org:443";
14283 std::string alternative_url = "https://alternative.example.org:443";
14284
14285 // Negotiate HTTP/1.1 with alternative.example.org.
14286 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614287 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14289
14290 // HTTP/1.1 data for |request1| and |request2|.
14291 MockWrite http_writes[] = {
14292 MockWrite(
14293 "GET / HTTP/1.1\r\n"
14294 "Host: alternative.example.org\r\n"
14295 "Connection: keep-alive\r\n\r\n"),
14296 MockWrite(
14297 "GET / HTTP/1.1\r\n"
14298 "Host: alternative.example.org\r\n"
14299 "Connection: keep-alive\r\n\r\n"),
14300 };
14301
14302 MockRead http_reads[] = {
14303 MockRead(
14304 "HTTP/1.1 200 OK\r\n"
14305 "Content-Type: text/html; charset=iso-8859-1\r\n"
14306 "Content-Length: 40\r\n\r\n"
14307 "first HTTP/1.1 response from alternative"),
14308 MockRead(
14309 "HTTP/1.1 200 OK\r\n"
14310 "Content-Type: text/html; charset=iso-8859-1\r\n"
14311 "Content-Length: 41\r\n\r\n"
14312 "second HTTP/1.1 response from alternative"),
14313 };
14314 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14315 http_writes, arraysize(http_writes));
14316 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14317
14318 // This test documents that an alternate Job should not pool to an already
14319 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614320 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214321 StaticSocketDataProvider data_refused;
14322 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14323 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14324
zhongyi3d4a55e72016-04-22 20:36:4614325 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914326 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014327 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214328 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114329 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214330 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114331 http_server_properties->SetHttp2AlternativeService(
14332 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214333
14334 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214335 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614336 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214337 request1.method = "GET";
14338 request1.url = GURL(alternative_url);
14339 request1.load_flags = 0;
14340 TestCompletionCallback callback1;
14341
tfarina42834112016-09-22 13:38:2014342 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114343 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614344 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214345 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214346 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214347 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214348 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214349 EXPECT_FALSE(response1->was_fetched_via_spdy);
14350 std::string response_data1;
bnc691fda62016-08-12 00:43:1614351 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214352 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14353
14354 // Request for origin.example.org, which has an alternative service. This
14355 // will start two Jobs: the alternative looks for connections to pool to,
14356 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614357 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214358 // this request fails.
bnc5452e2a2015-05-08 16:27:4214359 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614360 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214361 request2.method = "GET";
14362 request2.url = GURL(origin_url);
14363 request2.load_flags = 0;
14364 TestCompletionCallback callback2;
14365
tfarina42834112016-09-22 13:38:2014366 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114367 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214368
14369 // Another transaction to alternative. This is to test that the HTTP/1.1
14370 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214371 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614372 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214373 request3.method = "GET";
14374 request3.url = GURL(alternative_url);
14375 request3.load_flags = 0;
14376 TestCompletionCallback callback3;
14377
tfarina42834112016-09-22 13:38:2014378 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114379 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614380 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214381 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214382 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214383 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214384 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214385 EXPECT_FALSE(response3->was_fetched_via_spdy);
14386 std::string response_data3;
bnc691fda62016-08-12 00:43:1614387 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214388 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14389}
14390
bncd16676a2016-07-20 16:23:0114391TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314392 const std::string https_url = "https://www.example.org:8080/";
14393 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414394
rdsmithebb50aa2015-11-12 03:44:3814395 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114396 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814397
[email protected]8450d722012-07-02 19:14:0414398 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314399 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114400 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414401 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114402 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914403 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114404 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214405 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914406
14407 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914408 SpdyHeaderBlock req2_block;
14409 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314410 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914411 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914412 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114413 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514414 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414415
14416 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114417 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14418 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414419 };
14420
bncdf80d44fd2016-07-15 20:27:4114421 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514422 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114423 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514424 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114425 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14426 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814427 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114428 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814429 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514430 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114431 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314432 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114433 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314434 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114435 CreateMockRead(wrapped_resp1, 4),
14436 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314437 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114438 CreateMockRead(resp2, 8),
14439 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314440 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14441 };
[email protected]8450d722012-07-02 19:14:0414442
mmenke666a6fea2015-12-19 04:16:3314443 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14444 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414445 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714446 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414447
rdsmith82957ad2015-09-16 19:42:0314448 session_deps_.proxy_service =
14449 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114450 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714451 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414452 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614453 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414455 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614456 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14458 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414459
danakj1fd259a02016-04-16 03:17:0914460 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414461
14462 // Start the first transaction to set up the SpdySession
14463 HttpRequestInfo request1;
14464 request1.method = "GET";
14465 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414466 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014467 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414468 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014469 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414470
mmenke666a6fea2015-12-19 04:16:3314471 // This pause is a hack to avoid running into https://crbug.com/497228.
14472 data1.RunUntilPaused();
14473 base::RunLoop().RunUntilIdle();
14474 data1.Resume();
robpercival214763f2016-07-01 23:27:0114475 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414476 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14477
[email protected]f6c63db52013-02-02 00:35:2214478 LoadTimingInfo load_timing_info1;
14479 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14480 TestLoadTimingNotReusedWithPac(load_timing_info1,
14481 CONNECT_TIMING_HAS_SSL_TIMES);
14482
mmenke666a6fea2015-12-19 04:16:3314483 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414484 HttpRequestInfo request2;
14485 request2.method = "GET";
14486 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414487 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014488 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414489 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014490 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414491
mmenke666a6fea2015-12-19 04:16:3314492 // This pause is a hack to avoid running into https://crbug.com/497228.
14493 data1.RunUntilPaused();
14494 base::RunLoop().RunUntilIdle();
14495 data1.Resume();
robpercival214763f2016-07-01 23:27:0114496 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314497
[email protected]8450d722012-07-02 19:14:0414498 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214499
14500 LoadTimingInfo load_timing_info2;
14501 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14502 // The established SPDY sessions is considered reused by the HTTP request.
14503 TestLoadTimingReusedWithPac(load_timing_info2);
14504 // HTTP requests over a SPDY session should have a different connection
14505 // socket_log_id than requests over a tunnel.
14506 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414507}
14508
[email protected]2d88e7d2012-07-19 17:55:1714509// Test that in the case where we have a SPDY session to a SPDY proxy
14510// that we do not pool other origins that resolve to the same IP when
14511// the certificate does not match the new origin.
14512// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114513TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314514 const std::string url1 = "http://www.example.org/";
14515 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714516 const std::string ip_addr = "1.2.3.4";
14517
rdsmithebb50aa2015-11-12 03:44:3814518 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114519 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814520
[email protected]2d88e7d2012-07-19 17:55:1714521 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614522 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314523 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114524 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514525 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714526
14527 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114528 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714529 };
14530
bnc42331402016-07-25 13:36:1514531 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114532 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714533 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114534 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14535 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714536 };
14537
mmenke666a6fea2015-12-19 04:16:3314538 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14539 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214540 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914541 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714542 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14543 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314544 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714545
14546 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114547 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914548 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714549
14550 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114551 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714552 };
14553
bnc42331402016-07-25 13:36:1514554 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114555 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14556 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314557 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714558
mmenke666a6fea2015-12-19 04:16:3314559 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14560 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714561 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314562 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714563
14564 // Set up a proxy config that sends HTTP requests to a proxy, and
14565 // all others direct.
14566 ProxyConfig proxy_config;
14567 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
bnc87dcefc2017-05-25 12:47:5814568 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
14569 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), nullptr,
14570 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714571
bncce36dca22015-04-21 22:11:2314572 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614573 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714574 // Load a valid cert. Note, that this does not need to
14575 // be valid for proxy because the MockSSLClientSocket does
14576 // not actually verify it. But SpdySession will use this
14577 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314578 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214579 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314580 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14581 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714582
14583 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614584 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314585 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14586 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714587
bnc87dcefc2017-05-25 12:47:5814588 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314589 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714590 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714591
danakj1fd259a02016-04-16 03:17:0914592 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714593
14594 // Start the first transaction to set up the SpdySession
14595 HttpRequestInfo request1;
14596 request1.method = "GET";
14597 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714598 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014599 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714600 TestCompletionCallback callback1;
14601 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014602 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314603 // This pause is a hack to avoid running into https://crbug.com/497228.
14604 data1.RunUntilPaused();
14605 base::RunLoop().RunUntilIdle();
14606 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714607
robpercival214763f2016-07-01 23:27:0114608 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714609 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14610
14611 // Now, start the HTTP request
14612 HttpRequestInfo request2;
14613 request2.method = "GET";
14614 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714615 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014616 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714617 TestCompletionCallback callback2;
14618 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014619 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514620 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714621
14622 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114623 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714624 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14625}
14626
[email protected]85f97342013-04-17 06:12:2414627// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14628// error) in SPDY session, removes the socket from pool and closes the SPDY
14629// session. Verify that new url's from the same HttpNetworkSession (and a new
14630// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114631TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314632 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414633
14634 MockRead reads1[] = {
14635 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14636 };
14637
mmenke11eb5152015-06-09 14:50:5014638 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414639
bncdf80d44fd2016-07-15 20:27:4114640 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914641 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414642 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114643 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414644 };
14645
bnc42331402016-07-25 13:36:1514646 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114647 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414648 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114649 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14650 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414651 };
14652
mmenke11eb5152015-06-09 14:50:5014653 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14654 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414655
[email protected]85f97342013-04-17 06:12:2414656 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614657 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14659 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414660
14661 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614662 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014663 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14664 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414665
danakj1fd259a02016-04-16 03:17:0914666 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014667 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414668
14669 // Start the first transaction to set up the SpdySession and verify that
14670 // connection was closed.
14671 HttpRequestInfo request1;
14672 request1.method = "GET";
14673 request1.url = GURL(https_url);
14674 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014675 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414676 TestCompletionCallback callback1;
14677 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014678 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114679 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414680
14681 // Now, start the second request and make sure it succeeds.
14682 HttpRequestInfo request2;
14683 request2.method = "GET";
14684 request2.url = GURL(https_url);
14685 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014686 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414687 TestCompletionCallback callback2;
14688 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014689 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414690
robpercival214763f2016-07-01 23:27:0114691 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414692 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14693}
14694
bncd16676a2016-07-20 16:23:0114695TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314696 ClientSocketPoolManager::set_max_sockets_per_group(
14697 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14698 ClientSocketPoolManager::set_max_sockets_per_pool(
14699 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14700
14701 // Use two different hosts with different IPs so they don't get pooled.
14702 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14703 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314705
14706 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614707 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314708 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614709 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314710 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14711 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14712
bncdf80d44fd2016-07-15 20:27:4114713 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914714 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314715 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114716 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314717 };
bnc42331402016-07-25 13:36:1514718 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114719 SpdySerializedFrame host1_resp_body(
14720 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314721 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114722 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914723 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314724 };
14725
rdsmithebb50aa2015-11-12 03:44:3814726 // Use a separate test instance for the separate SpdySession that will be
14727 // created.
bncd16676a2016-07-20 16:23:0114728 SpdyTestUtil spdy_util_2;
bnc87dcefc2017-05-25 12:47:5814729 auto spdy1_data = base::MakeUnique<SequencedSocketData>(
14730 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14731 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0314732 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14733
bncdf80d44fd2016-07-15 20:27:4114734 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914735 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314736 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114737 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314738 };
bnc42331402016-07-25 13:36:1514739 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114740 SpdySerializedFrame host2_resp_body(
14741 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314742 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114743 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914744 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314745 };
14746
bnc87dcefc2017-05-25 12:47:5814747 auto spdy2_data = base::MakeUnique<SequencedSocketData>(
14748 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14749 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0314750 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14751
14752 MockWrite http_write[] = {
14753 MockWrite("GET / HTTP/1.1\r\n"
14754 "Host: www.a.com\r\n"
14755 "Connection: keep-alive\r\n\r\n"),
14756 };
14757
14758 MockRead http_read[] = {
14759 MockRead("HTTP/1.1 200 OK\r\n"),
14760 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14761 MockRead("Content-Length: 6\r\n\r\n"),
14762 MockRead("hello!"),
14763 };
14764 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14765 http_write, arraysize(http_write));
14766 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14767
14768 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014769 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314770 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314771 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614772 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314773
14774 TestCompletionCallback callback;
14775 HttpRequestInfo request1;
14776 request1.method = "GET";
14777 request1.url = GURL("https://www.a.com/");
14778 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814779 auto trans =
14780 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314781
tfarina42834112016-09-22 13:38:2014782 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14784 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314785
14786 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214787 ASSERT_TRUE(response);
14788 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214789 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314790 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214791 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314792
14793 std::string response_data;
robpercival214763f2016-07-01 23:27:0114794 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314795 EXPECT_EQ("hello!", response_data);
14796 trans.reset();
14797 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614798 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314799
14800 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014801 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314802 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314803 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614804 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314805 HttpRequestInfo request2;
14806 request2.method = "GET";
14807 request2.url = GURL("https://www.b.com/");
14808 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814809 trans =
14810 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314811
tfarina42834112016-09-22 13:38:2014812 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14814 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314815
14816 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214817 ASSERT_TRUE(response);
14818 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214819 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314820 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214821 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114822 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314823 EXPECT_EQ("hello!", response_data);
14824 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614825 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314826 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614827 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314828
14829 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014830 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314831 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314832 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614833 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314834 HttpRequestInfo request3;
14835 request3.method = "GET";
14836 request3.url = GURL("http://www.a.com/");
14837 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814838 trans =
14839 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314840
tfarina42834112016-09-22 13:38:2014841 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14843 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314844
14845 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214846 ASSERT_TRUE(response);
14847 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314848 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14849 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214850 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114851 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314852 EXPECT_EQ("hello!", response_data);
14853 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614854 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314855 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614856 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314857}
14858
bncd16676a2016-07-20 16:23:0114859TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414860 HttpRequestInfo request;
14861 request.method = "GET";
bncce36dca22015-04-21 22:11:2314862 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414863
danakj1fd259a02016-04-16 03:17:0914864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614865 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414866
ttuttled9dbc652015-09-29 20:00:5914867 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414868 StaticSocketDataProvider data;
14869 data.set_connect_data(mock_connect);
14870 session_deps_.socket_factory->AddSocketDataProvider(&data);
14871
14872 TestCompletionCallback callback;
14873
tfarina42834112016-09-22 13:38:2014874 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414876
14877 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114878 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414879
[email protected]79e1fd62013-06-20 06:50:0414880 // We don't care whether this succeeds or fails, but it shouldn't crash.
14881 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614882 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714883
14884 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614885 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714886 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114887 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914888
14889 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614890 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914891 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414892}
14893
bncd16676a2016-07-20 16:23:0114894TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414895 HttpRequestInfo request;
14896 request.method = "GET";
bncce36dca22015-04-21 22:11:2314897 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414898
danakj1fd259a02016-04-16 03:17:0914899 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614900 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414901
ttuttled9dbc652015-09-29 20:00:5914902 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414903 StaticSocketDataProvider data;
14904 data.set_connect_data(mock_connect);
14905 session_deps_.socket_factory->AddSocketDataProvider(&data);
14906
14907 TestCompletionCallback callback;
14908
tfarina42834112016-09-22 13:38:2014909 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414911
14912 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114913 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414914
[email protected]79e1fd62013-06-20 06:50:0414915 // We don't care whether this succeeds or fails, but it shouldn't crash.
14916 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614917 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714918
14919 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614920 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714921 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114922 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914923
14924 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614925 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914926 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414927}
14928
bncd16676a2016-07-20 16:23:0114929TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414930 HttpRequestInfo request;
14931 request.method = "GET";
bncce36dca22015-04-21 22:11:2314932 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414933
danakj1fd259a02016-04-16 03:17:0914934 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614935 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414936
14937 MockWrite data_writes[] = {
14938 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14939 };
14940 MockRead data_reads[] = {
14941 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14942 };
14943
14944 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14945 data_writes, arraysize(data_writes));
14946 session_deps_.socket_factory->AddSocketDataProvider(&data);
14947
14948 TestCompletionCallback callback;
14949
tfarina42834112016-09-22 13:38:2014950 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414952
14953 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114954 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414955
[email protected]79e1fd62013-06-20 06:50:0414956 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614957 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414958 EXPECT_TRUE(request_headers.HasHeader("Host"));
14959}
14960
bncd16676a2016-07-20 16:23:0114961TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414962 HttpRequestInfo request;
14963 request.method = "GET";
bncce36dca22015-04-21 22:11:2314964 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414965
danakj1fd259a02016-04-16 03:17:0914966 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414968
14969 MockWrite data_writes[] = {
14970 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14971 };
14972 MockRead data_reads[] = {
14973 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14974 };
14975
14976 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14977 data_writes, arraysize(data_writes));
14978 session_deps_.socket_factory->AddSocketDataProvider(&data);
14979
14980 TestCompletionCallback callback;
14981
tfarina42834112016-09-22 13:38:2014982 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414984
14985 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114986 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414987
[email protected]79e1fd62013-06-20 06:50:0414988 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614989 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414990 EXPECT_TRUE(request_headers.HasHeader("Host"));
14991}
14992
bncd16676a2016-07-20 16:23:0114993TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414994 HttpRequestInfo request;
14995 request.method = "GET";
bncce36dca22015-04-21 22:11:2314996 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414997
danakj1fd259a02016-04-16 03:17:0914998 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415000
15001 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315002 MockWrite(
15003 "GET / HTTP/1.1\r\n"
15004 "Host: www.example.org\r\n"
15005 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415006 };
15007 MockRead data_reads[] = {
15008 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15009 };
15010
15011 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15012 data_writes, arraysize(data_writes));
15013 session_deps_.socket_factory->AddSocketDataProvider(&data);
15014
15015 TestCompletionCallback callback;
15016
tfarina42834112016-09-22 13:38:2015017 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415019
15020 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115021 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415022
[email protected]79e1fd62013-06-20 06:50:0415023 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615024 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415025 EXPECT_TRUE(request_headers.HasHeader("Host"));
15026}
15027
bncd16676a2016-07-20 16:23:0115028TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415029 HttpRequestInfo request;
15030 request.method = "GET";
bncce36dca22015-04-21 22:11:2315031 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415032
danakj1fd259a02016-04-16 03:17:0915033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415035
15036 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315037 MockWrite(
15038 "GET / HTTP/1.1\r\n"
15039 "Host: www.example.org\r\n"
15040 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415041 };
15042 MockRead data_reads[] = {
15043 MockRead(ASYNC, ERR_CONNECTION_RESET),
15044 };
15045
15046 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15047 data_writes, arraysize(data_writes));
15048 session_deps_.socket_factory->AddSocketDataProvider(&data);
15049
15050 TestCompletionCallback callback;
15051
tfarina42834112016-09-22 13:38:2015052 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115053 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415054
15055 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115056 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415057
[email protected]79e1fd62013-06-20 06:50:0415058 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615059 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415060 EXPECT_TRUE(request_headers.HasHeader("Host"));
15061}
15062
bncd16676a2016-07-20 16:23:0115063TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415064 HttpRequestInfo request;
15065 request.method = "GET";
bncce36dca22015-04-21 22:11:2315066 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415067 request.extra_headers.SetHeader("X-Foo", "bar");
15068
danakj1fd259a02016-04-16 03:17:0915069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415071
15072 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315073 MockWrite(
15074 "GET / HTTP/1.1\r\n"
15075 "Host: www.example.org\r\n"
15076 "Connection: keep-alive\r\n"
15077 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415078 };
15079 MockRead data_reads[] = {
15080 MockRead("HTTP/1.1 200 OK\r\n"
15081 "Content-Length: 5\r\n\r\n"
15082 "hello"),
15083 MockRead(ASYNC, ERR_UNEXPECTED),
15084 };
15085
15086 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15087 data_writes, arraysize(data_writes));
15088 session_deps_.socket_factory->AddSocketDataProvider(&data);
15089
15090 TestCompletionCallback callback;
15091
tfarina42834112016-09-22 13:38:2015092 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415094
15095 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115096 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415097
15098 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615099 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415100 std::string foo;
15101 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15102 EXPECT_EQ("bar", foo);
15103}
15104
[email protected]bf828982013-08-14 18:01:4715105namespace {
15106
yhiranoa7e05bb2014-11-06 05:40:3915107// Fake HttpStream that simply records calls to SetPriority().
15108class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315109 public base::SupportsWeakPtr<FakeStream> {
15110 public:
15111 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015112 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315113
15114 RequestPriority priority() const { return priority_; }
15115
dchengb03027d2014-10-21 12:00:2015116 int InitializeStream(const HttpRequestInfo* request_info,
15117 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015118 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015119 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315120 return ERR_IO_PENDING;
15121 }
15122
dchengb03027d2014-10-21 12:00:2015123 int SendRequest(const HttpRequestHeaders& request_headers,
15124 HttpResponseInfo* response,
15125 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315126 ADD_FAILURE();
15127 return ERR_UNEXPECTED;
15128 }
15129
dchengb03027d2014-10-21 12:00:2015130 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315131 ADD_FAILURE();
15132 return ERR_UNEXPECTED;
15133 }
15134
dchengb03027d2014-10-21 12:00:2015135 int ReadResponseBody(IOBuffer* buf,
15136 int buf_len,
15137 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315138 ADD_FAILURE();
15139 return ERR_UNEXPECTED;
15140 }
15141
dchengb03027d2014-10-21 12:00:2015142 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315143
dchengb03027d2014-10-21 12:00:2015144 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315145 ADD_FAILURE();
15146 return false;
15147 }
15148
dchengb03027d2014-10-21 12:00:2015149 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315150 ADD_FAILURE();
15151 return false;
15152 }
15153
dchengb03027d2014-10-21 12:00:2015154 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315155
mmenkebd84c392015-09-02 14:12:3415156 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315157
sclittle4de1bab92015-09-22 21:28:2415158 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915159 ADD_FAILURE();
15160 return 0;
15161 }
15162
sclittlebe1ccf62015-09-02 19:40:3615163 int64_t GetTotalSentBytes() const override {
15164 ADD_FAILURE();
15165 return 0;
15166 }
15167
dchengb03027d2014-10-21 12:00:2015168 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315169 ADD_FAILURE();
15170 return false;
15171 }
15172
rchcd379012017-04-12 21:53:3215173 bool GetAlternativeService(
15174 AlternativeService* alternative_service) const override {
15175 ADD_FAILURE();
15176 return false;
15177 }
15178
dchengb03027d2014-10-21 12:00:2015179 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15180
15181 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315182 ADD_FAILURE();
15183 }
15184
ttuttled9dbc652015-09-29 20:00:5915185 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15186
nharper78e6d2b2016-09-21 05:42:3515187 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15188 TokenBindingType tb_type,
15189 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415190 ADD_FAILURE();
15191 return ERR_NOT_IMPLEMENTED;
15192 }
15193
dchengb03027d2014-10-21 12:00:2015194 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315195
zhongyica364fbb2015-12-12 03:39:1215196 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15197
dchengb03027d2014-10-21 12:00:2015198 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315199
yhiranoa7e05bb2014-11-06 05:40:3915200 HttpStream* RenewStreamForAuth() override { return NULL; }
15201
Andrey Kosyakov83a6eee2017-08-14 19:20:0415202 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15203
[email protected]e86839fd2013-08-14 18:29:0315204 private:
15205 RequestPriority priority_;
15206
15207 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15208};
15209
15210// Fake HttpStreamRequest that simply records calls to SetPriority()
15211// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715212class FakeStreamRequest : public HttpStreamRequest,
15213 public base::SupportsWeakPtr<FakeStreamRequest> {
15214 public:
[email protected]e86839fd2013-08-14 18:29:0315215 FakeStreamRequest(RequestPriority priority,
15216 HttpStreamRequest::Delegate* delegate)
15217 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415218 delegate_(delegate),
15219 websocket_stream_create_helper_(NULL) {}
15220
15221 FakeStreamRequest(RequestPriority priority,
15222 HttpStreamRequest::Delegate* delegate,
15223 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15224 : priority_(priority),
15225 delegate_(delegate),
15226 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315227
dchengb03027d2014-10-21 12:00:2015228 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715229
15230 RequestPriority priority() const { return priority_; }
15231
[email protected]831e4a32013-11-14 02:14:4415232 const WebSocketHandshakeStreamBase::CreateHelper*
15233 websocket_stream_create_helper() const {
15234 return websocket_stream_create_helper_;
15235 }
15236
[email protected]e86839fd2013-08-14 18:29:0315237 // Create a new FakeStream and pass it to the request's
15238 // delegate. Returns a weak pointer to the FakeStream.
15239 base::WeakPtr<FakeStream> FinishStreamRequest() {
bnc5029f4632017-06-08 16:19:0015240 auto fake_stream = base::MakeUnique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315241 // Do this before calling OnStreamReady() as OnStreamReady() may
15242 // immediately delete |fake_stream|.
15243 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015244 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315245 return weak_stream;
15246 }
15247
asanka681f02d2017-02-22 17:06:3915248 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715249 ADD_FAILURE();
15250 return ERR_UNEXPECTED;
15251 }
15252
dchengb03027d2014-10-21 12:00:2015253 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715254 ADD_FAILURE();
15255 return LoadState();
15256 }
15257
dchengb03027d2014-10-21 12:00:2015258 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715259
bnc94c92842016-09-21 15:22:5215260 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715261
bnc6227b26e2016-08-12 02:00:4315262 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715263
dchengb03027d2014-10-21 12:00:2015264 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715265
ttuttle1f2d7e92015-04-28 16:17:4715266 const ConnectionAttempts& connection_attempts() const override {
15267 static ConnectionAttempts no_attempts;
15268 return no_attempts;
15269 }
15270
[email protected]bf828982013-08-14 18:01:4715271 private:
15272 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315273 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415274 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715275
15276 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15277};
15278
15279// Fake HttpStreamFactory that vends FakeStreamRequests.
15280class FakeStreamFactory : public HttpStreamFactory {
15281 public:
15282 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015283 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715284
15285 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15286 // RequestStream() (which may be NULL if it was destroyed already).
15287 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15288 return last_stream_request_;
15289 }
15290
xunjieli96f2a402017-06-05 17:24:2715291 std::unique_ptr<HttpStreamRequest> RequestStream(
15292 const HttpRequestInfo& info,
15293 RequestPriority priority,
15294 const SSLConfig& server_ssl_config,
15295 const SSLConfig& proxy_ssl_config,
15296 HttpStreamRequest::Delegate* delegate,
15297 bool enable_ip_based_pooling,
15298 bool enable_alternative_services,
15299 const NetLogWithSource& net_log) override {
15300 auto fake_request = base::MakeUnique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715301 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715302 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715303 }
15304
xunjieli96f2a402017-06-05 17:24:2715305 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815306 const HttpRequestInfo& info,
15307 RequestPriority priority,
15308 const SSLConfig& server_ssl_config,
15309 const SSLConfig& proxy_ssl_config,
15310 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915311 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615312 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015313 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815314 NOTREACHED();
15315 return nullptr;
15316 }
15317
xunjieli96f2a402017-06-05 17:24:2715318 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715319 const HttpRequestInfo& info,
15320 RequestPriority priority,
15321 const SSLConfig& server_ssl_config,
15322 const SSLConfig& proxy_ssl_config,
15323 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615324 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915325 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615326 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015327 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715328 auto fake_request =
15329 base::MakeUnique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415330 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715331 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715332 }
15333
dchengb03027d2014-10-21 12:00:2015334 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915335 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715336 ADD_FAILURE();
15337 }
15338
dchengb03027d2014-10-21 12:00:2015339 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715340 ADD_FAILURE();
15341 return NULL;
15342 }
15343
xunjielif5267de2017-01-20 21:18:5715344 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15345 const std::string& parent_absolute_name) const override {
15346 ADD_FAILURE();
15347 }
15348
[email protected]bf828982013-08-14 18:01:4715349 private:
15350 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15351
15352 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15353};
15354
Adam Rice425cf122015-01-19 06:18:2415355// TODO(ricea): Maybe unify this with the one in
15356// url_request_http_job_unittest.cc ?
15357class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15358 public:
danakj1fd259a02016-04-16 03:17:0915359 FakeWebSocketBasicHandshakeStream(
15360 std::unique_ptr<ClientSocketHandle> connection,
15361 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215362 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415363
15364 // Fake implementation of HttpStreamBase methods.
15365 // This ends up being quite "real" because this object has to really send data
15366 // on the mock socket. It might be easier to use the real implementation, but
15367 // the fact that the WebSocket code is not compiled on iOS makes that
15368 // difficult.
15369 int InitializeStream(const HttpRequestInfo* request_info,
15370 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015371 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415372 const CompletionCallback& callback) override {
15373 state_.Initialize(request_info, priority, net_log, callback);
15374 return OK;
15375 }
15376
15377 int SendRequest(const HttpRequestHeaders& request_headers,
15378 HttpResponseInfo* response,
15379 const CompletionCallback& callback) override {
15380 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15381 response, callback);
15382 }
15383
15384 int ReadResponseHeaders(const CompletionCallback& callback) override {
15385 return parser()->ReadResponseHeaders(callback);
15386 }
15387
15388 int ReadResponseBody(IOBuffer* buf,
15389 int buf_len,
15390 const CompletionCallback& callback) override {
15391 NOTREACHED();
15392 return ERR_IO_PENDING;
15393 }
15394
15395 void Close(bool not_reusable) override {
15396 if (parser())
15397 parser()->Close(true);
15398 }
15399
15400 bool IsResponseBodyComplete() const override {
15401 NOTREACHED();
15402 return false;
15403 }
15404
Adam Rice425cf122015-01-19 06:18:2415405 bool IsConnectionReused() const override {
15406 NOTREACHED();
15407 return false;
15408 }
15409 void SetConnectionReused() override { NOTREACHED(); }
15410
mmenkebd84c392015-09-02 14:12:3415411 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415412
sclittle4de1bab92015-09-22 21:28:2415413 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415414 NOTREACHED();
15415 return 0;
15416 }
15417
sclittlebe1ccf62015-09-02 19:40:3615418 int64_t GetTotalSentBytes() const override {
15419 NOTREACHED();
15420 return 0;
15421 }
15422
Adam Rice425cf122015-01-19 06:18:2415423 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15424 NOTREACHED();
15425 return false;
15426 }
15427
rchcd379012017-04-12 21:53:3215428 bool GetAlternativeService(
15429 AlternativeService* alternative_service) const override {
15430 ADD_FAILURE();
15431 return false;
15432 }
15433
Adam Ricecb76ac62015-02-20 05:33:2515434 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415435
15436 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15437 NOTREACHED();
15438 }
15439
ttuttled9dbc652015-09-29 20:00:5915440 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15441
nharper78e6d2b2016-09-21 05:42:3515442 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15443 TokenBindingType tb_type,
15444 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415445 ADD_FAILURE();
15446 return ERR_NOT_IMPLEMENTED;
15447 }
15448
Adam Rice425cf122015-01-19 06:18:2415449 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15450
zhongyica364fbb2015-12-12 03:39:1215451 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15452
Adam Rice425cf122015-01-19 06:18:2415453 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15454
Adam Rice425cf122015-01-19 06:18:2415455 HttpStream* RenewStreamForAuth() override {
15456 NOTREACHED();
15457 return nullptr;
15458 }
15459
15460 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915461 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415462 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915463 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415464 }
15465
15466 private:
15467 HttpStreamParser* parser() const { return state_.parser(); }
15468 HttpBasicState state_;
15469
15470 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15471};
15472
[email protected]831e4a32013-11-14 02:14:4415473// TODO(yhirano): Split this class out into a net/websockets file, if it is
15474// worth doing.
15475class FakeWebSocketStreamCreateHelper :
15476 public WebSocketHandshakeStreamBase::CreateHelper {
15477 public:
bnc615cf2f2017-05-19 18:53:2615478 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915479 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315480 bool using_proxy) override {
bnc615cf2f2017-05-19 18:53:2615481 return base::MakeUnique<FakeWebSocketBasicHandshakeStream>(
15482 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415483 }
15484
dchengb03027d2014-10-21 12:00:2015485 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415486
danakj1fd259a02016-04-16 03:17:0915487 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415488 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915489 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415490 }
15491};
15492
[email protected]bf828982013-08-14 18:01:4715493} // namespace
15494
15495// Make sure that HttpNetworkTransaction passes on its priority to its
15496// stream request on start.
bncd16676a2016-07-20 16:23:0115497TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215499 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715500 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915501 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715502
krasinc06a72a2016-12-21 03:42:4615503 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115504 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715505
wezca1070932016-05-26 20:30:5215506 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715507
[email protected]bf828982013-08-14 18:01:4715508 TestCompletionCallback callback;
15509 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015510 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715511
15512 base::WeakPtr<FakeStreamRequest> fake_request =
15513 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215514 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715515 EXPECT_EQ(LOW, fake_request->priority());
15516}
15517
15518// Make sure that HttpNetworkTransaction passes on its priority
15519// updates to its stream request.
bncd16676a2016-07-20 16:23:0115520TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215522 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715523 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915524 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715525
krasinc06a72a2016-12-21 03:42:4615526 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115527 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715528
[email protected]bf828982013-08-14 18:01:4715529 TestCompletionCallback callback;
15530 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015531 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715532
15533 base::WeakPtr<FakeStreamRequest> fake_request =
15534 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215535 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715536 EXPECT_EQ(LOW, fake_request->priority());
15537
15538 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215539 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715540 EXPECT_EQ(LOWEST, fake_request->priority());
15541}
15542
[email protected]e86839fd2013-08-14 18:29:0315543// Make sure that HttpNetworkTransaction passes on its priority
15544// updates to its stream.
bncd16676a2016-07-20 16:23:0115545TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215547 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315548 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915549 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315550
krasinc06a72a2016-12-21 03:42:4615551 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115552 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315553
[email protected]e86839fd2013-08-14 18:29:0315554 TestCompletionCallback callback;
15555 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015556 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315557
15558 base::WeakPtr<FakeStreamRequest> fake_request =
15559 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215560 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315561 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215562 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315563 EXPECT_EQ(LOW, fake_stream->priority());
15564
15565 trans.SetPriority(LOWEST);
15566 EXPECT_EQ(LOWEST, fake_stream->priority());
15567}
15568
bncd16676a2016-07-20 16:23:0115569TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415570 // The same logic needs to be tested for both ws: and wss: schemes, but this
15571 // test is already parameterised on NextProto, so it uses a loop to verify
15572 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315573 std::string test_cases[] = {"ws://www.example.org/",
15574 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415575 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215577 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415578 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15579 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315580 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915581 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415582
krasinc06a72a2016-12-21 03:42:4615583 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115584 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415585 trans.SetWebSocketHandshakeStreamCreateHelper(
15586 &websocket_stream_create_helper);
15587
[email protected]831e4a32013-11-14 02:14:4415588 TestCompletionCallback callback;
15589 request.method = "GET";
15590 request.url = GURL(test_cases[i]);
15591
15592 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015593 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415594
15595 base::WeakPtr<FakeStreamRequest> fake_request =
15596 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215597 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415598 EXPECT_EQ(&websocket_stream_create_helper,
15599 fake_request->websocket_stream_create_helper());
15600 }
15601}
15602
[email protected]043b68c82013-08-22 23:41:5215603// Tests that when a used socket is returned to the SSL socket pool, it's closed
15604// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115605TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215606 ClientSocketPoolManager::set_max_sockets_per_group(
15607 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15608 ClientSocketPoolManager::set_max_sockets_per_pool(
15609 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15610
15611 // Set up SSL request.
15612
15613 HttpRequestInfo ssl_request;
15614 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315615 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215616
15617 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315618 MockWrite(
15619 "GET / HTTP/1.1\r\n"
15620 "Host: www.example.org\r\n"
15621 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215622 };
15623 MockRead ssl_reads[] = {
15624 MockRead("HTTP/1.1 200 OK\r\n"),
15625 MockRead("Content-Length: 11\r\n\r\n"),
15626 MockRead("hello world"),
15627 MockRead(SYNCHRONOUS, OK),
15628 };
15629 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15630 ssl_writes, arraysize(ssl_writes));
15631 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15632
15633 SSLSocketDataProvider ssl(ASYNC, OK);
15634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15635
15636 // Set up HTTP request.
15637
15638 HttpRequestInfo http_request;
15639 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315640 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215641
15642 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315643 MockWrite(
15644 "GET / HTTP/1.1\r\n"
15645 "Host: www.example.org\r\n"
15646 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215647 };
15648 MockRead http_reads[] = {
15649 MockRead("HTTP/1.1 200 OK\r\n"),
15650 MockRead("Content-Length: 7\r\n\r\n"),
15651 MockRead("falafel"),
15652 MockRead(SYNCHRONOUS, OK),
15653 };
15654 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15655 http_writes, arraysize(http_writes));
15656 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15657
danakj1fd259a02016-04-16 03:17:0915658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215659
15660 // Start the SSL request.
15661 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615662 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015663 ASSERT_EQ(ERR_IO_PENDING,
15664 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15665 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215666
15667 // Start the HTTP request. Pool should stall.
15668 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615669 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015670 ASSERT_EQ(ERR_IO_PENDING,
15671 http_trans.Start(&http_request, http_callback.callback(),
15672 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115673 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215674
15675 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115676 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215677 std::string response_data;
bnc691fda62016-08-12 00:43:1615678 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215679 EXPECT_EQ("hello world", response_data);
15680
15681 // The SSL socket should automatically be closed, so the HTTP request can
15682 // start.
dcheng48459ac22014-08-26 00:46:4115683 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15684 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215685
15686 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115687 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615688 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215689 EXPECT_EQ("falafel", response_data);
15690
dcheng48459ac22014-08-26 00:46:4115691 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215692}
15693
15694// Tests that when a SSL connection is established but there's no corresponding
15695// request that needs it, the new socket is closed if the transport socket pool
15696// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115697TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215698 ClientSocketPoolManager::set_max_sockets_per_group(
15699 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15700 ClientSocketPoolManager::set_max_sockets_per_pool(
15701 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15702
15703 // Set up an ssl request.
15704
15705 HttpRequestInfo ssl_request;
15706 ssl_request.method = "GET";
15707 ssl_request.url = GURL("https://www.foopy.com/");
15708
15709 // No data will be sent on the SSL socket.
15710 StaticSocketDataProvider ssl_data;
15711 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15712
15713 SSLSocketDataProvider ssl(ASYNC, OK);
15714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15715
15716 // Set up HTTP request.
15717
15718 HttpRequestInfo http_request;
15719 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315720 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215721
15722 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315723 MockWrite(
15724 "GET / HTTP/1.1\r\n"
15725 "Host: www.example.org\r\n"
15726 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215727 };
15728 MockRead http_reads[] = {
15729 MockRead("HTTP/1.1 200 OK\r\n"),
15730 MockRead("Content-Length: 7\r\n\r\n"),
15731 MockRead("falafel"),
15732 MockRead(SYNCHRONOUS, OK),
15733 };
15734 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15735 http_writes, arraysize(http_writes));
15736 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15737
danakj1fd259a02016-04-16 03:17:0915738 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215739
15740 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15741 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915742 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915743 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115744 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215745
15746 // Start the HTTP request. Pool should stall.
15747 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615748 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015749 ASSERT_EQ(ERR_IO_PENDING,
15750 http_trans.Start(&http_request, http_callback.callback(),
15751 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115752 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215753
15754 // The SSL connection will automatically be closed once the connection is
15755 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115756 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215757 std::string response_data;
bnc691fda62016-08-12 00:43:1615758 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215759 EXPECT_EQ("falafel", response_data);
15760
dcheng48459ac22014-08-26 00:46:4115761 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215762}
15763
bncd16676a2016-07-20 16:23:0115764TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915765 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215766 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715767 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215768 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415769
15770 HttpRequestInfo request;
15771 request.method = "POST";
15772 request.url = GURL("http://www.foo.com/");
15773 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415774
danakj1fd259a02016-04-16 03:17:0915775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415777 // Send headers successfully, but get an error while sending the body.
15778 MockWrite data_writes[] = {
15779 MockWrite("POST / HTTP/1.1\r\n"
15780 "Host: www.foo.com\r\n"
15781 "Connection: keep-alive\r\n"
15782 "Content-Length: 3\r\n\r\n"),
15783 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15784 };
15785
15786 MockRead data_reads[] = {
15787 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15788 MockRead("hello world"),
15789 MockRead(SYNCHRONOUS, OK),
15790 };
15791 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15792 arraysize(data_writes));
15793 session_deps_.socket_factory->AddSocketDataProvider(&data);
15794
15795 TestCompletionCallback callback;
15796
tfarina42834112016-09-22 13:38:2015797 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415799
15800 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115801 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415802
bnc691fda62016-08-12 00:43:1615803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215804 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415805
wezca1070932016-05-26 20:30:5215806 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415807 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15808
15809 std::string response_data;
bnc691fda62016-08-12 00:43:1615810 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115811 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415812 EXPECT_EQ("hello world", response_data);
15813}
15814
15815// This test makes sure the retry logic doesn't trigger when reading an error
15816// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115817TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415818 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415820 MockWrite data_writes[] = {
15821 MockWrite("GET / HTTP/1.1\r\n"
15822 "Host: www.foo.com\r\n"
15823 "Connection: keep-alive\r\n\r\n"),
15824 MockWrite("POST / HTTP/1.1\r\n"
15825 "Host: www.foo.com\r\n"
15826 "Connection: keep-alive\r\n"
15827 "Content-Length: 3\r\n\r\n"),
15828 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15829 };
15830
15831 MockRead data_reads[] = {
15832 MockRead("HTTP/1.1 200 Peachy\r\n"
15833 "Content-Length: 14\r\n\r\n"),
15834 MockRead("first response"),
15835 MockRead("HTTP/1.1 400 Not OK\r\n"
15836 "Content-Length: 15\r\n\r\n"),
15837 MockRead("second response"),
15838 MockRead(SYNCHRONOUS, OK),
15839 };
15840 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15841 arraysize(data_writes));
15842 session_deps_.socket_factory->AddSocketDataProvider(&data);
15843
15844 TestCompletionCallback callback;
15845 HttpRequestInfo request1;
15846 request1.method = "GET";
15847 request1.url = GURL("http://www.foo.com/");
15848 request1.load_flags = 0;
15849
bnc87dcefc2017-05-25 12:47:5815850 auto trans1 =
15851 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015852 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415854
15855 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115856 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415857
15858 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215859 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415860
wezca1070932016-05-26 20:30:5215861 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415862 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15863
15864 std::string response_data1;
15865 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115866 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415867 EXPECT_EQ("first response", response_data1);
15868 // Delete the transaction to release the socket back into the socket pool.
15869 trans1.reset();
15870
danakj1fd259a02016-04-16 03:17:0915871 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215872 element_readers.push_back(
bnc87dcefc2017-05-25 12:47:5815873 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215874 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415875
15876 HttpRequestInfo request2;
15877 request2.method = "POST";
15878 request2.url = GURL("http://www.foo.com/");
15879 request2.upload_data_stream = &upload_data_stream;
15880 request2.load_flags = 0;
15881
bnc691fda62016-08-12 00:43:1615882 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015883 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415885
15886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115887 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415888
bnc691fda62016-08-12 00:43:1615889 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215890 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415891
wezca1070932016-05-26 20:30:5215892 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415893 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15894
15895 std::string response_data2;
bnc691fda62016-08-12 00:43:1615896 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115897 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415898 EXPECT_EQ("second response", response_data2);
15899}
15900
bncd16676a2016-07-20 16:23:0115901TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415902 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915903 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215904 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715905 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215906 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415907
15908 HttpRequestInfo request;
15909 request.method = "POST";
15910 request.url = GURL("http://www.foo.com/");
15911 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415912
danakj1fd259a02016-04-16 03:17:0915913 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615914 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415915 // Send headers successfully, but get an error while sending the body.
15916 MockWrite data_writes[] = {
15917 MockWrite("POST / HTTP/1.1\r\n"
15918 "Host: www.foo.com\r\n"
15919 "Connection: keep-alive\r\n"
15920 "Content-Length: 3\r\n\r\n"
15921 "fo"),
15922 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15923 };
15924
15925 MockRead data_reads[] = {
15926 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15927 MockRead("hello world"),
15928 MockRead(SYNCHRONOUS, OK),
15929 };
15930 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15931 arraysize(data_writes));
15932 session_deps_.socket_factory->AddSocketDataProvider(&data);
15933
15934 TestCompletionCallback callback;
15935
tfarina42834112016-09-22 13:38:2015936 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415938
15939 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115940 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415941
bnc691fda62016-08-12 00:43:1615942 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215943 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415944
wezca1070932016-05-26 20:30:5215945 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415946 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15947
15948 std::string response_data;
bnc691fda62016-08-12 00:43:1615949 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115950 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415951 EXPECT_EQ("hello world", response_data);
15952}
15953
15954// This tests the more common case than the previous test, where headers and
15955// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115956TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715957 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415958
15959 HttpRequestInfo request;
15960 request.method = "POST";
15961 request.url = GURL("http://www.foo.com/");
15962 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415963
danakj1fd259a02016-04-16 03:17:0915964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415966 // Send headers successfully, but get an error while sending the body.
15967 MockWrite data_writes[] = {
15968 MockWrite("POST / HTTP/1.1\r\n"
15969 "Host: www.foo.com\r\n"
15970 "Connection: keep-alive\r\n"
15971 "Transfer-Encoding: chunked\r\n\r\n"),
15972 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15973 };
15974
15975 MockRead data_reads[] = {
15976 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15977 MockRead("hello world"),
15978 MockRead(SYNCHRONOUS, OK),
15979 };
15980 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15981 arraysize(data_writes));
15982 session_deps_.socket_factory->AddSocketDataProvider(&data);
15983
15984 TestCompletionCallback callback;
15985
tfarina42834112016-09-22 13:38:2015986 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115987 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415988 // Make sure the headers are sent before adding a chunk. This ensures that
15989 // they can't be merged with the body in a single send. Not currently
15990 // necessary since a chunked body is never merged with headers, but this makes
15991 // the test more future proof.
15992 base::RunLoop().RunUntilIdle();
15993
mmenkecbc2b712014-10-09 20:29:0715994 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415995
15996 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115997 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415998
bnc691fda62016-08-12 00:43:1615999 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216000 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416001
wezca1070932016-05-26 20:30:5216002 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416003 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16004
16005 std::string response_data;
bnc691fda62016-08-12 00:43:1616006 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116007 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416008 EXPECT_EQ("hello world", response_data);
16009}
16010
bncd16676a2016-07-20 16:23:0116011TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916012 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216013 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716014 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216015 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416016
16017 HttpRequestInfo request;
16018 request.method = "POST";
16019 request.url = GURL("http://www.foo.com/");
16020 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416021
danakj1fd259a02016-04-16 03:17:0916022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616023 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416024
16025 MockWrite data_writes[] = {
16026 MockWrite("POST / HTTP/1.1\r\n"
16027 "Host: www.foo.com\r\n"
16028 "Connection: keep-alive\r\n"
16029 "Content-Length: 3\r\n\r\n"),
16030 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16031 };
16032
16033 MockRead data_reads[] = {
16034 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16035 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16036 MockRead("hello world"),
16037 MockRead(SYNCHRONOUS, OK),
16038 };
16039 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16040 arraysize(data_writes));
16041 session_deps_.socket_factory->AddSocketDataProvider(&data);
16042
16043 TestCompletionCallback callback;
16044
tfarina42834112016-09-22 13:38:2016045 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416047
16048 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116049 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416050
bnc691fda62016-08-12 00:43:1616051 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216052 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416053
wezca1070932016-05-26 20:30:5216054 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416055 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16056
16057 std::string response_data;
bnc691fda62016-08-12 00:43:1616058 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116059 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416060 EXPECT_EQ("hello world", response_data);
16061}
16062
bncd16676a2016-07-20 16:23:0116063TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916064 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216065 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716066 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216067 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416068
16069 HttpRequestInfo request;
16070 request.method = "POST";
16071 request.url = GURL("http://www.foo.com/");
16072 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416073
danakj1fd259a02016-04-16 03:17:0916074 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416076 // Send headers successfully, but get an error while sending the body.
16077 MockWrite data_writes[] = {
16078 MockWrite("POST / HTTP/1.1\r\n"
16079 "Host: www.foo.com\r\n"
16080 "Connection: keep-alive\r\n"
16081 "Content-Length: 3\r\n\r\n"),
16082 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16083 };
16084
16085 MockRead data_reads[] = {
16086 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16087 MockRead("hello world"),
16088 MockRead(SYNCHRONOUS, OK),
16089 };
16090 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16091 arraysize(data_writes));
16092 session_deps_.socket_factory->AddSocketDataProvider(&data);
16093
16094 TestCompletionCallback callback;
16095
tfarina42834112016-09-22 13:38:2016096 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416098
16099 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116100 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416101}
16102
bncd16676a2016-07-20 16:23:0116103TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416104 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916105 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216106 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716107 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216108 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416109
16110 HttpRequestInfo request;
16111 request.method = "POST";
16112 request.url = GURL("http://www.foo.com/");
16113 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416114
danakj1fd259a02016-04-16 03:17:0916115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616116 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416117 // Send headers successfully, but get an error while sending the body.
16118 MockWrite data_writes[] = {
16119 MockWrite("POST / HTTP/1.1\r\n"
16120 "Host: www.foo.com\r\n"
16121 "Connection: keep-alive\r\n"
16122 "Content-Length: 3\r\n\r\n"),
16123 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16124 };
16125
16126 MockRead data_reads[] = {
16127 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16128 MockRead("HTTP/1.0 302 Redirect\r\n"),
16129 MockRead("Location: http://somewhere-else.com/\r\n"),
16130 MockRead("Content-Length: 0\r\n\r\n"),
16131 MockRead(SYNCHRONOUS, OK),
16132 };
16133 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16134 arraysize(data_writes));
16135 session_deps_.socket_factory->AddSocketDataProvider(&data);
16136
16137 TestCompletionCallback callback;
16138
tfarina42834112016-09-22 13:38:2016139 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416141
16142 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116143 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416144}
16145
bncd16676a2016-07-20 16:23:0116146TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916147 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216148 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716149 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216150 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416151
16152 HttpRequestInfo request;
16153 request.method = "POST";
16154 request.url = GURL("http://www.foo.com/");
16155 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416156
danakj1fd259a02016-04-16 03:17:0916157 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416159 // Send headers successfully, but get an error while sending the body.
16160 MockWrite data_writes[] = {
16161 MockWrite("POST / HTTP/1.1\r\n"
16162 "Host: www.foo.com\r\n"
16163 "Connection: keep-alive\r\n"
16164 "Content-Length: 3\r\n\r\n"),
16165 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16166 };
16167
16168 MockRead data_reads[] = {
16169 MockRead("HTTP 0.9 rocks!"),
16170 MockRead(SYNCHRONOUS, OK),
16171 };
16172 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16173 arraysize(data_writes));
16174 session_deps_.socket_factory->AddSocketDataProvider(&data);
16175
16176 TestCompletionCallback callback;
16177
tfarina42834112016-09-22 13:38:2016178 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116179 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416180
16181 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116182 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416183}
16184
bncd16676a2016-07-20 16:23:0116185TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916186 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216187 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716188 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216189 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416190
16191 HttpRequestInfo request;
16192 request.method = "POST";
16193 request.url = GURL("http://www.foo.com/");
16194 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416195
danakj1fd259a02016-04-16 03:17:0916196 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616197 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416198 // Send headers successfully, but get an error while sending the body.
16199 MockWrite data_writes[] = {
16200 MockWrite("POST / HTTP/1.1\r\n"
16201 "Host: www.foo.com\r\n"
16202 "Connection: keep-alive\r\n"
16203 "Content-Length: 3\r\n\r\n"),
16204 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16205 };
16206
16207 MockRead data_reads[] = {
16208 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16209 MockRead(SYNCHRONOUS, OK),
16210 };
16211 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16212 arraysize(data_writes));
16213 session_deps_.socket_factory->AddSocketDataProvider(&data);
16214
16215 TestCompletionCallback callback;
16216
tfarina42834112016-09-22 13:38:2016217 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416219
16220 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116221 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416222}
16223
Adam Rice425cf122015-01-19 06:18:2416224// Verify that proxy headers are not sent to the destination server when
16225// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116226TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416227 HttpRequestInfo request;
16228 request.method = "GET";
bncce36dca22015-04-21 22:11:2316229 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416230 AddWebSocketHeaders(&request.extra_headers);
16231
16232 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316233 session_deps_.proxy_service =
16234 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416235
danakj1fd259a02016-04-16 03:17:0916236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416237
16238 // Since a proxy is configured, try to establish a tunnel.
16239 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716240 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16241 "Host: www.example.org:443\r\n"
16242 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416243
16244 // After calling trans->RestartWithAuth(), this is the request we should
16245 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716246 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16247 "Host: www.example.org:443\r\n"
16248 "Proxy-Connection: keep-alive\r\n"
16249 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416250
rsleevidb16bb02015-11-12 23:47:1716251 MockWrite("GET / HTTP/1.1\r\n"
16252 "Host: www.example.org\r\n"
16253 "Connection: Upgrade\r\n"
16254 "Upgrade: websocket\r\n"
16255 "Origin: http://www.example.org\r\n"
16256 "Sec-WebSocket-Version: 13\r\n"
16257 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416258 };
16259
16260 // The proxy responds to the connect with a 407, using a persistent
16261 // connection.
16262 MockRead data_reads[] = {
16263 // No credentials.
16264 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16265 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416266 MockRead("Content-Length: 0\r\n"),
16267 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416268
16269 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16270
16271 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16272 MockRead("Upgrade: websocket\r\n"),
16273 MockRead("Connection: Upgrade\r\n"),
16274 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16275 };
16276
16277 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16278 arraysize(data_writes));
16279 session_deps_.socket_factory->AddSocketDataProvider(&data);
16280 SSLSocketDataProvider ssl(ASYNC, OK);
16281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16282
bnc87dcefc2017-05-25 12:47:5816283 auto trans =
16284 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416285 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16286 trans->SetWebSocketHandshakeStreamCreateHelper(
16287 &websocket_stream_create_helper);
16288
16289 {
16290 TestCompletionCallback callback;
16291
tfarina42834112016-09-22 13:38:2016292 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116293 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416294
16295 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116296 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416297 }
16298
16299 const HttpResponseInfo* response = trans->GetResponseInfo();
16300 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216301 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416302 EXPECT_EQ(407, response->headers->response_code());
16303
16304 {
16305 TestCompletionCallback callback;
16306
16307 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16308 callback.callback());
robpercival214763f2016-07-01 23:27:0116309 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416310
16311 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116312 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416313 }
16314
16315 response = trans->GetResponseInfo();
16316 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216317 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416318
16319 EXPECT_EQ(101, response->headers->response_code());
16320
16321 trans.reset();
16322 session->CloseAllConnections();
16323}
16324
16325// Verify that proxy headers are not sent to the destination server when
16326// establishing a tunnel for an insecure WebSocket connection.
16327// This requires the authentication info to be injected into the auth cache
16328// due to crbug.com/395064
16329// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116330TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416331 HttpRequestInfo request;
16332 request.method = "GET";
bncce36dca22015-04-21 22:11:2316333 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416334 AddWebSocketHeaders(&request.extra_headers);
16335
16336 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316337 session_deps_.proxy_service =
16338 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416339
danakj1fd259a02016-04-16 03:17:0916340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416341
16342 MockWrite data_writes[] = {
16343 // Try to establish a tunnel for the WebSocket connection, with
16344 // credentials. Because WebSockets have a separate set of socket pools,
16345 // they cannot and will not use the same TCP/IP connection as the
16346 // preflight HTTP request.
16347 MockWrite(
bncce36dca22015-04-21 22:11:2316348 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16349 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416350 "Proxy-Connection: keep-alive\r\n"
16351 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16352
16353 MockWrite(
16354 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316355 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416356 "Connection: Upgrade\r\n"
16357 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316358 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416359 "Sec-WebSocket-Version: 13\r\n"
16360 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16361 };
16362
16363 MockRead data_reads[] = {
16364 // HTTP CONNECT with credentials.
16365 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16366
16367 // WebSocket connection established inside tunnel.
16368 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16369 MockRead("Upgrade: websocket\r\n"),
16370 MockRead("Connection: Upgrade\r\n"),
16371 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16372 };
16373
16374 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16375 arraysize(data_writes));
16376 session_deps_.socket_factory->AddSocketDataProvider(&data);
16377
16378 session->http_auth_cache()->Add(
16379 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16380 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16381
bnc87dcefc2017-05-25 12:47:5816382 auto trans =
16383 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416384 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16385 trans->SetWebSocketHandshakeStreamCreateHelper(
16386 &websocket_stream_create_helper);
16387
16388 TestCompletionCallback callback;
16389
tfarina42834112016-09-22 13:38:2016390 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116391 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416392
16393 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116394 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416395
16396 const HttpResponseInfo* response = trans->GetResponseInfo();
16397 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216398 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416399
16400 EXPECT_EQ(101, response->headers->response_code());
16401
16402 trans.reset();
16403 session->CloseAllConnections();
16404}
16405
bncd16676a2016-07-20 16:23:0116406TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916407 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216408 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716409 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216410 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216411
16412 HttpRequestInfo request;
16413 request.method = "POST";
16414 request.url = GURL("http://www.foo.com/");
16415 request.upload_data_stream = &upload_data_stream;
16416
danakj1fd259a02016-04-16 03:17:0916417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216419 MockWrite data_writes[] = {
16420 MockWrite("POST / HTTP/1.1\r\n"
16421 "Host: www.foo.com\r\n"
16422 "Connection: keep-alive\r\n"
16423 "Content-Length: 3\r\n\r\n"),
16424 MockWrite("foo"),
16425 };
16426
16427 MockRead data_reads[] = {
16428 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16429 MockRead(SYNCHRONOUS, OK),
16430 };
16431 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16432 arraysize(data_writes));
16433 session_deps_.socket_factory->AddSocketDataProvider(&data);
16434
16435 TestCompletionCallback callback;
16436
16437 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016438 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116439 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216440
16441 std::string response_data;
bnc691fda62016-08-12 00:43:1616442 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216443
16444 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616445 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216446 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616447 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216448}
16449
bncd16676a2016-07-20 16:23:0116450TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916451 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216452 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716453 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216454 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216455
16456 HttpRequestInfo request;
16457 request.method = "POST";
16458 request.url = GURL("http://www.foo.com/");
16459 request.upload_data_stream = &upload_data_stream;
16460
danakj1fd259a02016-04-16 03:17:0916461 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216463 MockWrite data_writes[] = {
16464 MockWrite("POST / HTTP/1.1\r\n"
16465 "Host: www.foo.com\r\n"
16466 "Connection: keep-alive\r\n"
16467 "Content-Length: 3\r\n\r\n"),
16468 MockWrite("foo"),
16469 };
16470
16471 MockRead data_reads[] = {
16472 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16473 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16474 MockRead(SYNCHRONOUS, OK),
16475 };
16476 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16477 arraysize(data_writes));
16478 session_deps_.socket_factory->AddSocketDataProvider(&data);
16479
16480 TestCompletionCallback callback;
16481
16482 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016483 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116484 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216485
16486 std::string response_data;
bnc691fda62016-08-12 00:43:1616487 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216488
16489 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616490 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216491 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616492 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216493}
16494
bncd16676a2016-07-20 16:23:0116495TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216496 ChunkedUploadDataStream upload_data_stream(0);
16497
16498 HttpRequestInfo request;
16499 request.method = "POST";
16500 request.url = GURL("http://www.foo.com/");
16501 request.upload_data_stream = &upload_data_stream;
16502
danakj1fd259a02016-04-16 03:17:0916503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616504 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216505 // Send headers successfully, but get an error while sending the body.
16506 MockWrite data_writes[] = {
16507 MockWrite("POST / HTTP/1.1\r\n"
16508 "Host: www.foo.com\r\n"
16509 "Connection: keep-alive\r\n"
16510 "Transfer-Encoding: chunked\r\n\r\n"),
16511 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16512 };
16513
16514 MockRead data_reads[] = {
16515 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16516 MockRead(SYNCHRONOUS, OK),
16517 };
16518 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16519 arraysize(data_writes));
16520 session_deps_.socket_factory->AddSocketDataProvider(&data);
16521
16522 TestCompletionCallback callback;
16523
16524 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016525 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216526
16527 base::RunLoop().RunUntilIdle();
16528 upload_data_stream.AppendData("f", 1, false);
16529
16530 base::RunLoop().RunUntilIdle();
16531 upload_data_stream.AppendData("oo", 2, true);
16532
robpercival214763f2016-07-01 23:27:0116533 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216534
16535 std::string response_data;
bnc691fda62016-08-12 00:43:1616536 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216537
16538 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616539 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216540 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616541 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216542}
16543
rdsmith1d343be52016-10-21 20:37:5016544// Confirm that transactions whose throttle is created in (and stays in)
16545// the unthrottled state are not blocked.
16546TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16547 TestNetworkStreamThrottler* throttler(nullptr);
16548 std::unique_ptr<HttpNetworkSession> session(
16549 CreateSessionWithThrottler(&session_deps_, &throttler));
16550
16551 // Send a simple request and make sure it goes through.
16552 HttpRequestInfo request;
16553 request.method = "GET";
16554 request.url = GURL("http://www.example.org/");
16555
bnc87dcefc2017-05-25 12:47:5816556 auto trans =
16557 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016558
16559 MockWrite data_writes[] = {
16560 MockWrite("GET / HTTP/1.1\r\n"
16561 "Host: www.example.org\r\n"
16562 "Connection: keep-alive\r\n\r\n"),
16563 };
16564 MockRead data_reads[] = {
16565 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16566 MockRead(SYNCHRONOUS, OK),
16567 };
16568 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16569 arraysize(data_writes));
16570 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16571
16572 TestCompletionCallback callback;
16573 trans->Start(&request, callback.callback(), NetLogWithSource());
16574 EXPECT_EQ(OK, callback.WaitForResult());
16575}
16576
16577// Confirm requests can be blocked by a throttler, and are resumed
16578// when the throttle is unblocked.
16579TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16580 TestNetworkStreamThrottler* throttler(nullptr);
16581 std::unique_ptr<HttpNetworkSession> session(
16582 CreateSessionWithThrottler(&session_deps_, &throttler));
16583
16584 // Send a simple request and make sure it goes through.
16585 HttpRequestInfo request;
16586 request.method = "GET";
16587 request.url = GURL("http://www.example.org/");
16588
16589 MockWrite data_writes[] = {
16590 MockWrite("GET / HTTP/1.1\r\n"
16591 "Host: www.example.org\r\n"
16592 "Connection: keep-alive\r\n\r\n"),
16593 };
16594 MockRead data_reads[] = {
16595 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16596 MockRead(SYNCHRONOUS, OK),
16597 };
16598 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16599 arraysize(data_writes));
16600 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16601
16602 // Start a request that will be throttled at start; confirm it
16603 // doesn't complete.
16604 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816605 auto trans =
16606 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016607
16608 TestCompletionCallback callback;
16609 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16610 EXPECT_EQ(ERR_IO_PENDING, rv);
16611
16612 base::RunLoop().RunUntilIdle();
16613 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16614 EXPECT_FALSE(callback.have_result());
16615
16616 // Confirm the request goes on to complete when unthrottled.
16617 throttler->UnthrottleAllRequests();
16618 base::RunLoop().RunUntilIdle();
16619 ASSERT_TRUE(callback.have_result());
16620 EXPECT_EQ(OK, callback.WaitForResult());
16621}
16622
16623// Destroy a request while it's throttled.
16624TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16625 TestNetworkStreamThrottler* throttler(nullptr);
16626 std::unique_ptr<HttpNetworkSession> session(
16627 CreateSessionWithThrottler(&session_deps_, &throttler));
16628
16629 // Send a simple request and make sure it goes through.
16630 HttpRequestInfo request;
16631 request.method = "GET";
16632 request.url = GURL("http://www.example.org/");
16633
16634 MockWrite data_writes[] = {
16635 MockWrite("GET / HTTP/1.1\r\n"
16636 "Host: www.example.org\r\n"
16637 "Connection: keep-alive\r\n\r\n"),
16638 };
16639 MockRead data_reads[] = {
16640 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16641 MockRead(SYNCHRONOUS, OK),
16642 };
16643 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16644 arraysize(data_writes));
16645 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16646
16647 // Start a request that will be throttled at start; confirm it
16648 // doesn't complete.
16649 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816650 auto trans =
16651 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016652
16653 TestCompletionCallback callback;
16654 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16655 EXPECT_EQ(ERR_IO_PENDING, rv);
16656
16657 base::RunLoop().RunUntilIdle();
16658 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16659 EXPECT_FALSE(callback.have_result());
16660
16661 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16662 trans.reset();
16663 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16664}
16665
16666// Confirm the throttler receives SetPriority calls.
16667TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16668 TestNetworkStreamThrottler* throttler(nullptr);
16669 std::unique_ptr<HttpNetworkSession> session(
16670 CreateSessionWithThrottler(&session_deps_, &throttler));
16671
16672 // Send a simple request and make sure it goes through.
16673 HttpRequestInfo request;
16674 request.method = "GET";
16675 request.url = GURL("http://www.example.org/");
16676
16677 MockWrite data_writes[] = {
16678 MockWrite("GET / HTTP/1.1\r\n"
16679 "Host: www.example.org\r\n"
16680 "Connection: keep-alive\r\n\r\n"),
16681 };
16682 MockRead data_reads[] = {
16683 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16684 MockRead(SYNCHRONOUS, OK),
16685 };
16686 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16687 arraysize(data_writes));
16688 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16689
16690 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816691 auto trans = base::MakeUnique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016692 // Start the transaction to associate a throttle with it.
16693 TestCompletionCallback callback;
16694 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16695 EXPECT_EQ(ERR_IO_PENDING, rv);
16696
16697 EXPECT_EQ(0, throttler->num_set_priority_calls());
16698 trans->SetPriority(LOW);
16699 EXPECT_EQ(1, throttler->num_set_priority_calls());
16700 EXPECT_EQ(LOW, throttler->last_priority_set());
16701
16702 throttler->UnthrottleAllRequests();
16703 base::RunLoop().RunUntilIdle();
16704 ASSERT_TRUE(callback.have_result());
16705 EXPECT_EQ(OK, callback.WaitForResult());
16706}
16707
16708// Confirm that unthrottling from a SetPriority call by the
16709// throttler works properly.
16710TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16711 TestNetworkStreamThrottler* throttler(nullptr);
16712 std::unique_ptr<HttpNetworkSession> session(
16713 CreateSessionWithThrottler(&session_deps_, &throttler));
16714
16715 // Send a simple request and make sure it goes through.
16716 HttpRequestInfo request;
16717 request.method = "GET";
16718 request.url = GURL("http://www.example.org/");
16719
16720 MockWrite data_writes[] = {
16721 MockWrite("GET / HTTP/1.1\r\n"
16722 "Host: www.example.org\r\n"
16723 "Connection: keep-alive\r\n\r\n"),
16724 };
16725 MockRead data_reads[] = {
16726 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16727 MockRead(SYNCHRONOUS, OK),
16728 };
16729 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16730 arraysize(data_writes));
16731 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16732
16733 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16734 data_writes, arraysize(data_writes));
16735 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16736
16737 // Start a request that will be throttled at start; confirm it
16738 // doesn't complete.
16739 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816740 auto trans =
16741 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016742
16743 TestCompletionCallback callback;
16744 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16745 EXPECT_EQ(ERR_IO_PENDING, rv);
16746
16747 base::RunLoop().RunUntilIdle();
16748 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16749 EXPECT_FALSE(callback.have_result());
16750
16751 // Create a new request, call SetPriority on it to unthrottle,
16752 // and make sure that allows the original request to complete.
bnc87dcefc2017-05-25 12:47:5816753 auto trans1 = base::MakeUnique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5016754 throttler->set_priority_change_closure(
16755 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16756 base::Unretained(throttler)));
16757
16758 // Start the transaction to associate a throttle with it.
16759 TestCompletionCallback callback1;
16760 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16761 EXPECT_EQ(ERR_IO_PENDING, rv);
16762
16763 trans1->SetPriority(IDLE);
16764
16765 base::RunLoop().RunUntilIdle();
16766 ASSERT_TRUE(callback.have_result());
16767 EXPECT_EQ(OK, callback.WaitForResult());
16768 ASSERT_TRUE(callback1.have_result());
16769 EXPECT_EQ(OK, callback1.WaitForResult());
16770}
16771
16772// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5816773void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5016774
16775// Confirm that destroying a transaction from a SetPriority call by the
16776// throttler works properly.
16777TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16778 TestNetworkStreamThrottler* throttler(nullptr);
16779 std::unique_ptr<HttpNetworkSession> session(
16780 CreateSessionWithThrottler(&session_deps_, &throttler));
16781
16782 // Send a simple request and make sure it goes through.
16783 HttpRequestInfo request;
16784 request.method = "GET";
16785 request.url = GURL("http://www.example.org/");
16786
16787 MockWrite data_writes[] = {
16788 MockWrite("GET / HTTP/1.1\r\n"
16789 "Host: www.example.org\r\n"
16790 "Connection: keep-alive\r\n\r\n"),
16791 };
16792 MockRead data_reads[] = {
16793 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16794 MockRead(SYNCHRONOUS, OK),
16795 };
16796 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16797 arraysize(data_writes));
16798 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16799
16800 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16801 data_writes, arraysize(data_writes));
16802 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16803
16804 // Start a request that will be throttled at start; confirm it
16805 // doesn't complete.
16806 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816807 auto trans =
16808 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016809
16810 TestCompletionCallback callback;
16811 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16812 EXPECT_EQ(ERR_IO_PENDING, rv);
16813
16814 base::RunLoop().RunUntilIdle();
16815 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16816 EXPECT_FALSE(callback.have_result());
16817
16818 // Arrange for the set priority call on the above transaction to delete
16819 // the transaction.
bnc87dcefc2017-05-25 12:47:5816820 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5016821 throttler->set_priority_change_closure(
16822 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16823
16824 // Call it and check results (partially a "doesn't crash" test).
16825 trans_ptr->SetPriority(IDLE);
16826 trans_ptr = nullptr; // No longer a valid pointer.
16827
16828 base::RunLoop().RunUntilIdle();
16829 ASSERT_FALSE(callback.have_result());
16830}
16831
nharperb7441ef2016-01-25 23:54:1416832#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116833TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416834 const std::string https_url = "https://www.example.com";
16835 HttpRequestInfo request;
16836 request.url = GURL(https_url);
16837 request.method = "GET";
16838
16839 SSLSocketDataProvider ssl(ASYNC, OK);
16840 ssl.token_binding_negotiated = true;
16841 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616842 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416843 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16844
bnc42331402016-07-25 13:36:1516845 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116846 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16847 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416848 MockRead(ASYNC, ERR_IO_PENDING)};
16849 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16850 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5816851 session_deps_.channel_id_service =
16852 base::MakeUnique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0916853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416854
16855 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16856 TestCompletionCallback callback;
16857 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016858 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1016859
16860 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416861
16862 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16863 HttpRequestHeaders headers;
16864 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16865 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16866}
16867#endif // !defined(OS_IOS)
16868
eustasc7d27da2017-04-06 10:33:2016869void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
16870 const std::string& accept_encoding,
16871 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0316872 const std::string& location,
eustasc7d27da2017-04-06 10:33:2016873 bool should_match) {
16874 HttpRequestInfo request;
16875 request.method = "GET";
16876 request.url = GURL("http://www.foo.com/");
16877 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
16878 accept_encoding);
16879
16880 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
16881 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16882 // Send headers successfully, but get an error while sending the body.
16883 MockWrite data_writes[] = {
16884 MockWrite("GET / HTTP/1.1\r\n"
16885 "Host: www.foo.com\r\n"
16886 "Connection: keep-alive\r\n"
16887 "Accept-Encoding: "),
16888 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
16889 };
16890
sky50576f32017-05-01 19:28:0316891 std::string response_code = "200 OK";
16892 std::string extra;
16893 if (!location.empty()) {
16894 response_code = "301 Redirect\r\nLocation: ";
16895 response_code.append(location);
16896 }
16897
eustasc7d27da2017-04-06 10:33:2016898 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0316899 MockRead("HTTP/1.0 "),
16900 MockRead(response_code.data()),
16901 MockRead("\r\nContent-Encoding: "),
16902 MockRead(content_encoding.data()),
16903 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2016904 MockRead(SYNCHRONOUS, OK),
16905 };
16906 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16907 arraysize(data_writes));
16908 session_deps->socket_factory->AddSocketDataProvider(&data);
16909
16910 TestCompletionCallback callback;
16911
16912 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16914
16915 rv = callback.WaitForResult();
16916 if (should_match) {
16917 EXPECT_THAT(rv, IsOk());
16918 } else {
16919 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
16920 }
16921}
16922
16923TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0316924 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2016925}
16926
16927TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0316928 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
16929 true);
eustasc7d27da2017-04-06 10:33:2016930}
16931
16932TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
16933 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0316934 "", false);
16935}
16936
16937TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
16938 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
16939 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2016940}
16941
xunjieli96f2a402017-06-05 17:24:2716942TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
16943 ProxyConfig proxy_config;
16944 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
16945 proxy_config.set_pac_mandatory(true);
16946 MockAsyncProxyResolver resolver;
16947 session_deps_.proxy_service.reset(new ProxyService(
16948 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
16949 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
16950
16951 HttpRequestInfo request;
16952 request.method = "GET";
16953 request.url = GURL("http://www.example.org/");
16954
16955 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16956 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16957
16958 TestCompletionCallback callback;
16959
16960 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16962 EXPECT_THAT(callback.WaitForResult(),
16963 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
16964}
16965
16966TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
16967 ProxyConfig proxy_config;
16968 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
16969 proxy_config.set_pac_mandatory(true);
16970 MockAsyncProxyResolverFactory* proxy_resolver_factory =
16971 new MockAsyncProxyResolverFactory(false);
16972 MockAsyncProxyResolver resolver;
16973 session_deps_.proxy_service.reset(
16974 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
16975 base::WrapUnique(proxy_resolver_factory), nullptr));
16976 HttpRequestInfo request;
16977 request.method = "GET";
16978 request.url = GURL("http://www.example.org/");
16979
16980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16982
16983 TestCompletionCallback callback;
16984 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16986
16987 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
16988 ERR_FAILED, &resolver);
16989 EXPECT_THAT(callback.WaitForResult(),
16990 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
16991}
16992
16993TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
16994 session_deps_.proxy_service =
16995 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
16996 session_deps_.enable_quic = false;
16997 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16998
16999 HttpRequestInfo request;
17000 request.method = "GET";
17001 request.url = GURL("http://www.example.org/");
17002
17003 TestCompletionCallback callback;
17004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17005 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17007
17008 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17009}
17010
[email protected]89ceba9a2009-03-21 03:46:0617011} // namespace net