blob: 24fafb279b244777d8149f5411b765db7170f757 [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"
tbansal28e68f82016-02-04 02:56:1574#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1175#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4476#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1577#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0378#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4779#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0280#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0781#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4482#include "net/socket/socket_test_util.h"
83#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0684#include "net/spdy/chromium/spdy_session.h"
85#include "net/spdy/chromium/spdy_session_pool.h"
86#include "net/spdy/chromium/spdy_test_util_common.h"
87#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1488#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5789#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0390#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_config_service_defaults.h"
92#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5493#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1194#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0195#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1096#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:4397#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:4498#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:1899#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52100#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15101#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27102#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52103
robpercival214763f2016-07-01 23:27:01104using net::test::IsError;
105using net::test::IsOk;
106
[email protected]ad65a3e2013-12-25 18:18:01107using base::ASCIIToUTF16;
108
initial.commit586acc5fe2008-07-26 22:42:52109//-----------------------------------------------------------------------------
110
ttuttle859dc7a2015-04-23 19:42:29111namespace net {
112
[email protected]13c8a092010-07-29 06:15:44113namespace {
114
rdsmith1d343be52016-10-21 20:37:50115class TestNetworkStreamThrottler : public NetworkThrottleManager {
116 public:
117 TestNetworkStreamThrottler()
118 : throttle_new_requests_(false),
119 num_set_priority_calls_(0),
120 last_priority_set_(IDLE) {}
121
122 ~TestNetworkStreamThrottler() override {
123 EXPECT_TRUE(outstanding_throttles_.empty());
124 }
125
126 // NetworkThrottleManager
127 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
128 RequestPriority priority,
129 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58130 auto test_throttle =
131 base::MakeUnique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50132 outstanding_throttles_.insert(test_throttle.get());
133 return std::move(test_throttle);
134 }
135
136 void UnthrottleAllRequests() {
137 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25138 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24139 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50140 throttle->Unthrottle();
141 }
142 }
143
144 void set_throttle_new_requests(bool throttle_new_requests) {
145 throttle_new_requests_ = throttle_new_requests;
146 }
147
148 // Includes both throttled and unthrottled throttles.
149 size_t num_outstanding_requests() const {
150 return outstanding_throttles_.size();
151 }
152
153 int num_set_priority_calls() const { return num_set_priority_calls_; }
154 RequestPriority last_priority_set() const { return last_priority_set_; }
155 void set_priority_change_closure(
156 const base::Closure& priority_change_closure) {
157 priority_change_closure_ = priority_change_closure;
158 }
159
160 private:
161 class TestThrottle : public NetworkThrottleManager::Throttle {
162 public:
163 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
164
165 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24166 bool IsBlocked() const override { return throttled_; }
167 RequestPriority Priority() const override {
168 NOTREACHED();
169 return IDLE;
170 }
rdsmith1d343be52016-10-21 20:37:50171 void SetPriority(RequestPriority priority) override {
172 throttler_->SetPriorityCalled(priority);
173 }
174
175 TestThrottle(bool throttled,
176 ThrottleDelegate* delegate,
177 TestNetworkStreamThrottler* throttler)
178 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
179
180 void Unthrottle() {
181 EXPECT_TRUE(throttled_);
182
183 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24184 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50185 }
186
187 bool throttled_;
188 ThrottleDelegate* delegate_;
189 TestNetworkStreamThrottler* throttler_;
190 };
191
192 void OnThrottleDestroyed(TestThrottle* throttle) {
193 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
194 outstanding_throttles_.erase(throttle);
195 }
196
197 void SetPriorityCalled(RequestPriority priority) {
198 ++num_set_priority_calls_;
199 last_priority_set_ = priority;
200 if (!priority_change_closure_.is_null())
201 priority_change_closure_.Run();
202 }
203
204 // Includes both throttled and unthrottled throttles.
205 std::set<TestThrottle*> outstanding_throttles_;
206 bool throttle_new_requests_;
207 int num_set_priority_calls_;
208 RequestPriority last_priority_set_;
209 base::Closure priority_change_closure_;
210
211 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
212};
213
[email protected]42cba2fb2013-03-29 19:58:57214const base::string16 kBar(ASCIIToUTF16("bar"));
215const base::string16 kBar2(ASCIIToUTF16("bar2"));
216const base::string16 kBar3(ASCIIToUTF16("bar3"));
217const base::string16 kBaz(ASCIIToUTF16("baz"));
218const base::string16 kFirst(ASCIIToUTF16("first"));
219const base::string16 kFoo(ASCIIToUTF16("foo"));
220const base::string16 kFoo2(ASCIIToUTF16("foo2"));
221const base::string16 kFoo3(ASCIIToUTF16("foo3"));
222const base::string16 kFou(ASCIIToUTF16("fou"));
223const base::string16 kSecond(ASCIIToUTF16("second"));
224const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
225const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44226
bnc2df4b522016-07-08 18:17:43227const char kAlternativeServiceHttpHeader[] =
228 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
229
ttuttle859dc7a2015-04-23 19:42:29230int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
231 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
232 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02233}
234
ttuttle859dc7a2015-04-23 19:42:29235int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
236 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
237 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02238}
239
ttuttle859dc7a2015-04-23 19:42:29240bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
241 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
242 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52243}
244
[email protected]f3da152d2012-06-02 01:00:57245// Takes in a Value created from a NetLogHttpResponseParameter, and returns
246// a JSONified list of headers as a single string. Uses single quotes instead
247// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27248bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57249 if (!params)
250 return false;
[email protected]ea5ef4c2013-06-13 22:50:27251 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57252 if (!params->GetList("headers", &header_list))
253 return false;
254 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34255 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28256 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57257 return true;
258}
259
[email protected]029c83b62013-01-24 05:28:20260// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
261// used.
ttuttle859dc7a2015-04-23 19:42:29262void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20263 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19264 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25265
[email protected]029c83b62013-01-24 05:28:20266 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
267 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
268
ttuttle859dc7a2015-04-23 19:42:29269 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20270 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25271
272 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25273
[email protected]3b23a222013-05-15 21:33:25274 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25275 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
276 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25277 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25278}
279
[email protected]029c83b62013-01-24 05:28:20280// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
281// used.
ttuttle859dc7a2015-04-23 19:42:29282void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25283 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20284 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19285 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20286
287 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
288 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
289
ttuttle859dc7a2015-04-23 19:42:29290 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
291 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20292 EXPECT_LE(load_timing_info.connect_timing.connect_end,
293 load_timing_info.send_start);
294
295 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20296
[email protected]3b23a222013-05-15 21:33:25297 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20298 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
299 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25300 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20301}
302
303// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
304// used.
ttuttle859dc7a2015-04-23 19:42:29305void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20306 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19307 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20308
ttuttle859dc7a2015-04-23 19:42:29309 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20310
311 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
312 EXPECT_LE(load_timing_info.proxy_resolve_start,
313 load_timing_info.proxy_resolve_end);
314 EXPECT_LE(load_timing_info.proxy_resolve_end,
315 load_timing_info.send_start);
316 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20317
[email protected]3b23a222013-05-15 21:33:25318 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20319 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
320 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25321 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20322}
323
324// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
325// used.
ttuttle859dc7a2015-04-23 19:42:29326void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20327 int connect_timing_flags) {
328 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19329 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20330
331 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
332 EXPECT_LE(load_timing_info.proxy_resolve_start,
333 load_timing_info.proxy_resolve_end);
334 EXPECT_LE(load_timing_info.proxy_resolve_end,
335 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29336 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
337 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20338 EXPECT_LE(load_timing_info.connect_timing.connect_end,
339 load_timing_info.send_start);
340
341 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20342
[email protected]3b23a222013-05-15 21:33:25343 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20344 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
345 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25346 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25347}
348
ttuttle859dc7a2015-04-23 19:42:29349void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24350 headers->SetHeader("Connection", "Upgrade");
351 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23352 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24353 headers->SetHeader("Sec-WebSocket-Version", "13");
354 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
355}
356
danakj1fd259a02016-04-16 03:17:09357std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42358 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34359 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14360}
361
rdsmith1d343be52016-10-21 20:37:50362// Note that the pointer written into |*throttler| will only be valid
363// for the lifetime of the returned HttpNetworkSession.
364std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
365 SpdySessionDependencies* session_deps,
366 TestNetworkStreamThrottler** throttler) {
367 std::unique_ptr<HttpNetworkSession> session(
368 SpdySessionDependencies::SpdyCreateSession(session_deps));
369
bnc87dcefc2017-05-25 12:47:58370 auto owned_throttler = base::MakeUnique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50371 *throttler = owned_throttler.get();
372
373 HttpNetworkSessionPeer peer(session.get());
374 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
375
376 return session;
377}
378
[email protected]448d4ca52012-03-04 04:12:23379} // namespace
380
bncd16676a2016-07-20 16:23:01381class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03382 public:
bncd16676a2016-07-20 16:23:01383 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03384 // Important to restore the per-pool limit first, since the pool limit must
385 // always be greater than group limit, and the tests reduce both limits.
386 ClientSocketPoolManager::set_max_sockets_per_pool(
387 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
388 ClientSocketPoolManager::set_max_sockets_per_group(
389 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
390 }
391
[email protected]e3ceb682011-06-28 23:55:46392 protected:
[email protected]23e482282013-06-14 16:08:02393 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15394 : ssl_(ASYNC, OK),
395 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03396 HttpNetworkSession::NORMAL_SOCKET_POOL)),
397 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
398 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28399 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03400 }
[email protected]bb88e1d32013-05-03 23:11:07401
[email protected]e3ceb682011-06-28 23:55:46402 struct SimpleGetHelperResult {
403 int rv;
404 std::string status_line;
405 std::string response_data;
sclittlefb249892015-09-10 21:33:22406 int64_t total_received_bytes;
407 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25408 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47409 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59410 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46411 };
412
dcheng67be2b1f2014-10-27 21:47:29413 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50414 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55415 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54416 }
417
dcheng67be2b1f2014-10-27 21:47:29418 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50419 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55420 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09421 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55422 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09423 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50424 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55425 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09426 }
427
[email protected]202965992011-12-07 23:04:51428 // Either |write_failure| specifies a write failure or |read_failure|
429 // specifies a read failure when using a reused socket. In either case, the
430 // failure should cause the network transaction to resend the request, and the
431 // other argument should be NULL.
432 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
433 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52434
[email protected]a34f61ee2014-03-18 20:59:49435 // Either |write_failure| specifies a write failure or |read_failure|
436 // specifies a read failure when using a reused socket. In either case, the
437 // failure should cause the network transaction to resend the request, and the
438 // other argument should be NULL.
439 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10440 const MockRead* read_failure,
441 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49442
[email protected]5a60c8b2011-10-19 20:14:29443 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
444 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15445 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52446
[email protected]ff007e162009-05-23 09:13:15447 HttpRequestInfo request;
448 request.method = "GET";
bncce36dca22015-04-21 22:11:23449 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52450
vishal.b62985ca92015-04-17 08:45:51451 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07452 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16454 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27455
[email protected]5a60c8b2011-10-19 20:14:29456 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07457 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29458 }
initial.commit586acc5fe2008-07-26 22:42:52459
[email protected]49639fa2011-12-20 23:22:41460 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52461
eroman24bc6a12015-05-06 19:55:48462 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16463 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52465
[email protected]ff007e162009-05-23 09:13:15466 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16467 out.total_received_bytes = trans.GetTotalReceivedBytes();
468 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25469
470 // Even in the failure cases that use this function, connections are always
471 // successfully established before the error.
bnc691fda62016-08-12 00:43:16472 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25473 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
474
[email protected]ff007e162009-05-23 09:13:15475 if (out.rv != OK)
476 return out;
477
bnc691fda62016-08-12 00:43:16478 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50479 // Can't use ASSERT_* inside helper functions like this, so
480 // return an error.
wezca1070932016-05-26 20:30:52481 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50482 out.rv = ERR_UNEXPECTED;
483 return out;
484 }
[email protected]ff007e162009-05-23 09:13:15485 out.status_line = response->headers->GetStatusLine();
486
[email protected]80a09a82012-11-16 17:40:06487 EXPECT_EQ("127.0.0.1", response->socket_address.host());
488 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19489
ttuttled9dbc652015-09-29 20:00:59490 bool got_endpoint =
bnc691fda62016-08-12 00:43:16491 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59492 EXPECT_EQ(got_endpoint,
493 out.remote_endpoint_after_start.address().size() > 0);
494
bnc691fda62016-08-12 00:43:16495 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01496 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40497
mmenke43758e62015-05-04 21:09:46498 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40499 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39500 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00501 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
502 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39503 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00504 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
505 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15506
[email protected]f3da152d2012-06-02 01:00:57507 std::string line;
508 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
509 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
510
[email protected]79e1fd62013-06-20 06:50:04511 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16512 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04513 std::string value;
514 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23515 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04516 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
517 EXPECT_EQ("keep-alive", value);
518
519 std::string response_headers;
520 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23521 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04522 response_headers);
[email protected]3deb9a52010-11-11 00:24:40523
bnc691fda62016-08-12 00:43:16524 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22525 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16526 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22527
bnc691fda62016-08-12 00:43:16528 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47529 return out;
[email protected]ff007e162009-05-23 09:13:15530 }
initial.commit586acc5fe2008-07-26 22:42:52531
[email protected]5a60c8b2011-10-19 20:14:29532 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
533 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22534 MockWrite data_writes[] = {
535 MockWrite("GET / HTTP/1.1\r\n"
536 "Host: www.example.org\r\n"
537 "Connection: keep-alive\r\n\r\n"),
538 };
[email protected]5a60c8b2011-10-19 20:14:29539
sclittlefb249892015-09-10 21:33:22540 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
541 arraysize(data_writes));
542 StaticSocketDataProvider* data[] = {&reads};
543 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
544
545 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
546 out.total_sent_bytes);
547 return out;
[email protected]b8015c42013-12-24 15:18:19548 }
549
bnc032658ba2016-09-26 18:17:15550 void AddSSLSocketData() {
551 ssl_.next_proto = kProtoHTTP2;
552 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
553 ASSERT_TRUE(ssl_.cert);
554 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
555 }
556
[email protected]ff007e162009-05-23 09:13:15557 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
558 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52559
[email protected]ff007e162009-05-23 09:13:15560 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07561
562 void BypassHostCacheOnRefreshHelper(int load_flags);
563
564 void CheckErrorIsPassedBack(int error, IoMode mode);
565
[email protected]4bd46222013-05-14 19:32:23566 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07567 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15568 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03569
570 // Original socket limits. Some tests set these. Safest to always restore
571 // them once each test has been run.
572 int old_max_group_sockets_;
573 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15574};
[email protected]231d5a32008-09-13 00:45:27575
[email protected]448d4ca52012-03-04 04:12:23576namespace {
577
ryansturm49a8cb12016-06-15 16:51:09578class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27579 public:
ryansturm49a8cb12016-06-15 16:51:09580 BeforeHeadersSentHandler()
581 : observed_before_headers_sent_with_proxy_(false),
582 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27583
ryansturm49a8cb12016-06-15 16:51:09584 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
585 HttpRequestHeaders* request_headers) {
586 observed_before_headers_sent_ = true;
587 if (!proxy_info.is_http() && !proxy_info.is_https() &&
588 !proxy_info.is_quic()) {
589 return;
590 }
591 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27592 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
593 }
594
ryansturm49a8cb12016-06-15 16:51:09595 bool observed_before_headers_sent_with_proxy() const {
596 return observed_before_headers_sent_with_proxy_;
597 }
598
599 bool observed_before_headers_sent() const {
600 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27601 }
602
603 std::string observed_proxy_server_uri() const {
604 return observed_proxy_server_uri_;
605 }
606
607 private:
ryansturm49a8cb12016-06-15 16:51:09608 bool observed_before_headers_sent_with_proxy_;
609 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27610 std::string observed_proxy_server_uri_;
611
ryansturm49a8cb12016-06-15 16:51:09612 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27613};
614
[email protected]15a5ccf82008-10-23 19:57:43615// Fill |str| with a long header list that consumes >= |size| bytes.
616void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51617 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19618 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
619 const int sizeof_row = strlen(row);
620 const int num_rows = static_cast<int>(
621 ceil(static_cast<float>(size) / sizeof_row));
622 const int sizeof_data = num_rows * sizeof_row;
623 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43624 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51625
[email protected]4ddaf2502008-10-23 18:26:19626 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43627 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19628}
629
thakis84dff942015-07-28 20:47:38630#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29631// Alternative functions that eliminate randomness and dependency on the local
632// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14633void MockGenerateRandom1(uint8_t* output, size_t n) {
634 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
635 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29636 static size_t current_byte = 0;
637 for (size_t i = 0; i < n; ++i) {
638 output[i] = bytes[current_byte++];
639 current_byte %= arraysize(bytes);
640 }
641}
642
avibf0746c2015-12-09 19:53:14643void MockGenerateRandom2(uint8_t* output, size_t n) {
644 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
645 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
646 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29647 static size_t current_byte = 0;
648 for (size_t i = 0; i < n; ++i) {
649 output[i] = bytes[current_byte++];
650 current_byte %= arraysize(bytes);
651 }
652}
653
[email protected]fe2bc6a2009-03-23 16:52:20654std::string MockGetHostName() {
655 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29656}
thakis84dff942015-07-28 20:47:38657#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29658
[email protected]e60e47a2010-07-14 03:37:18659template<typename ParentPool>
660class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31661 public:
[email protected]9e1bdd32011-02-03 21:48:34662 CaptureGroupNameSocketPool(HostResolver* host_resolver,
663 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18664
[email protected]d80a4322009-08-14 07:07:49665 const std::string last_group_name_received() const {
666 return last_group_name_;
667 }
668
dmichaeld6e570d2014-12-18 22:30:57669 int RequestSocket(const std::string& group_name,
670 const void* socket_params,
671 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15672 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57673 ClientSocketHandle* handle,
674 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20675 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31676 last_group_name_ = group_name;
677 return ERR_IO_PENDING;
678 }
dmichaeld6e570d2014-12-18 22:30:57679 void CancelRequest(const std::string& group_name,
680 ClientSocketHandle* handle) override {}
681 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09682 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57683 int id) override {}
684 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23685 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57686 int IdleSocketCount() const override { return 0; }
687 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31688 return 0;
689 }
dmichaeld6e570d2014-12-18 22:30:57690 LoadState GetLoadState(const std::string& group_name,
691 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31692 return LOAD_STATE_IDLE;
693 }
dmichaeld6e570d2014-12-18 22:30:57694 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26695 return base::TimeDelta();
696 }
[email protected]d80a4322009-08-14 07:07:49697
698 private:
[email protected]04e5be32009-06-26 20:00:31699 std::string last_group_name_;
700};
701
[email protected]ab739042011-04-07 15:22:28702typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
703CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13704typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
705CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06706typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11707CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18708typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
709CaptureGroupNameSSLSocketPool;
710
rkaplowd90695c2015-03-25 22:12:41711template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18712CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34713 HostResolver* host_resolver,
714 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21715 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18716
hashimoto0d3e4fb2015-01-09 05:02:50717template <>
[email protected]2df19bb2010-08-25 20:13:46718CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21719 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34720 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41721 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50722}
[email protected]2df19bb2010-08-25 20:13:46723
[email protected]007b3f82013-04-09 08:46:45724template <>
[email protected]e60e47a2010-07-14 03:37:18725CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21726 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34727 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45728 : SSLClientSocketPool(0,
729 0,
[email protected]007b3f82013-04-09 08:46:45730 cert_verifier,
731 NULL,
732 NULL,
[email protected]284303b62013-11-28 15:11:54733 NULL,
eranm6571b2b2014-12-03 15:53:23734 NULL,
[email protected]007b3f82013-04-09 08:46:45735 std::string(),
736 NULL,
737 NULL,
738 NULL,
739 NULL,
740 NULL,
[email protected]8e458552014-08-05 00:02:15741 NULL) {
742}
[email protected]2227c692010-05-04 15:36:11743
[email protected]231d5a32008-09-13 00:45:27744//-----------------------------------------------------------------------------
745
[email protected]79cb5c12011-09-12 13:12:04746// Helper functions for validating that AuthChallengeInfo's are correctly
747// configured for common cases.
748bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
749 if (!auth_challenge)
750 return false;
751 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43752 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04753 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19754 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04755 return true;
756}
757
758bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
759 if (!auth_challenge)
760 return false;
761 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43762 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
763 EXPECT_EQ("MyRealm1", auth_challenge->realm);
764 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
765 return true;
766}
767
768bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
769 if (!auth_challenge)
770 return false;
771 EXPECT_TRUE(auth_challenge->is_proxy);
772 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04773 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19774 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04775 return true;
776}
777
778bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
779 if (!auth_challenge)
780 return false;
781 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43782 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04783 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19784 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04785 return true;
786}
787
thakis84dff942015-07-28 20:47:38788#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04789bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
790 if (!auth_challenge)
791 return false;
792 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43793 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04794 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19795 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04796 return true;
797}
thakis84dff942015-07-28 20:47:38798#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04799
[email protected]448d4ca52012-03-04 04:12:23800} // namespace
801
bncd16676a2016-07-20 16:23:01802TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16804 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27805}
806
bncd16676a2016-07-20 16:23:01807TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27808 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35809 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
810 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06811 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27812 };
[email protected]31a2bfe2010-02-09 08:03:39813 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
814 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01815 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27816 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
817 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22818 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
819 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47820 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59821
822 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27823}
824
825// Response with no status line.
bncd16676a2016-07-20 16:23:01826TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27827 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35828 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06829 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27830 };
[email protected]31a2bfe2010-02-09 08:03:39831 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
832 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41833 EXPECT_THAT(out.rv, IsOk());
834 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
835 EXPECT_EQ("hello world", out.response_data);
836 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
837 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27838}
839
mmenkea7da6da2016-09-01 21:56:52840// Response with no status line, and a weird port. Should fail by default.
841TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
842 MockRead data_reads[] = {
843 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
844 };
845
846 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
847 session_deps_.socket_factory->AddSocketDataProvider(&data);
848
849 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
850
krasinc06a72a2016-12-21 03:42:46851 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58852 auto trans =
853 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52854
mmenkea7da6da2016-09-01 21:56:52855 request.method = "GET";
856 request.url = GURL("http://www.example.com:2000/");
857 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20858 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52859 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
860}
861
862// Response with no status line, and a weird port. Option to allow weird ports
863// enabled.
864TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
865 MockRead data_reads[] = {
866 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
867 };
868
869 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
870 session_deps_.socket_factory->AddSocketDataProvider(&data);
871 session_deps_.http_09_on_non_default_ports_enabled = true;
872 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
873
krasinc06a72a2016-12-21 03:42:46874 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58875 auto trans =
876 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52877
mmenkea7da6da2016-09-01 21:56:52878 request.method = "GET";
879 request.url = GURL("http://www.example.com:2000/");
880 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20881 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52882 EXPECT_THAT(callback.GetResult(rv), IsOk());
883
884 const HttpResponseInfo* info = trans->GetResponseInfo();
885 ASSERT_TRUE(info->headers);
886 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
887
888 // Don't bother to read the body - that's verified elsewhere, important thing
889 // is that the option to allow HTTP/0.9 on non-default ports is respected.
890}
891
[email protected]231d5a32008-09-13 00:45:27892// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01893TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27894 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35895 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06896 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27897 };
[email protected]31a2bfe2010-02-09 08:03:39898 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
899 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01900 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27901 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
902 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22903 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
904 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27905}
906
907// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01908TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27909 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35910 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06911 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27912 };
[email protected]31a2bfe2010-02-09 08:03:39913 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
914 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01915 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27916 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
917 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22918 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
919 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27920}
921
922// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01923TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27924 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35925 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06926 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27927 };
[email protected]31a2bfe2010-02-09 08:03:39928 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
929 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41930 EXPECT_THAT(out.rv, IsOk());
931 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
932 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
933 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
934 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27935}
936
937// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01938TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27939 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35940 MockRead("\n"),
941 MockRead("\n"),
942 MockRead("Q"),
943 MockRead("J"),
944 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06945 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27946 };
[email protected]31a2bfe2010-02-09 08:03:39947 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
948 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01949 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27950 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
951 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22952 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
953 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27954}
955
956// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01957TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27958 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35959 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06960 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27961 };
[email protected]31a2bfe2010-02-09 08:03:39962 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
963 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41964 EXPECT_THAT(out.rv, IsOk());
965 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
966 EXPECT_EQ("HTT", out.response_data);
967 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
968 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52969}
970
[email protected]f9d44aa2008-09-23 23:57:17971// Simulate a 204 response, lacking a Content-Length header, sent over a
972// persistent connection. The response should still terminate since a 204
973// cannot have a response body.
bncd16676a2016-07-20 16:23:01974TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19975 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17976 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35977 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19978 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06979 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17980 };
[email protected]31a2bfe2010-02-09 08:03:39981 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
982 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01983 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17984 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
985 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22986 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
987 int64_t response_size = reads_size - strlen(junk);
988 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17989}
990
[email protected]0877e3d2009-10-17 22:29:57991// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01992TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19993 std::string final_chunk = "0\r\n\r\n";
994 std::string extra_data = "HTTP/1.1 200 OK\r\n";
995 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57996 MockRead data_reads[] = {
997 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
998 MockRead("5\r\nHello\r\n"),
999 MockRead("1\r\n"),
1000 MockRead(" \r\n"),
1001 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191002 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061003 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571004 };
[email protected]31a2bfe2010-02-09 08:03:391005 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1006 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011007 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571008 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1009 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221010 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1011 int64_t response_size = reads_size - extra_data.size();
1012 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571013}
1014
[email protected]9fe44f52010-09-23 18:36:001015// Next tests deal with http://crbug.com/56344.
1016
bncd16676a2016-07-20 16:23:011017TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001018 MultipleContentLengthHeadersNoTransferEncoding) {
1019 MockRead data_reads[] = {
1020 MockRead("HTTP/1.1 200 OK\r\n"),
1021 MockRead("Content-Length: 10\r\n"),
1022 MockRead("Content-Length: 5\r\n\r\n"),
1023 };
1024 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1025 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011026 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001027}
1028
bncd16676a2016-07-20 16:23:011029TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041030 DuplicateContentLengthHeadersNoTransferEncoding) {
1031 MockRead data_reads[] = {
1032 MockRead("HTTP/1.1 200 OK\r\n"),
1033 MockRead("Content-Length: 5\r\n"),
1034 MockRead("Content-Length: 5\r\n\r\n"),
1035 MockRead("Hello"),
1036 };
1037 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1038 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011039 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041040 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1041 EXPECT_EQ("Hello", out.response_data);
1042}
1043
bncd16676a2016-07-20 16:23:011044TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041045 ComplexContentLengthHeadersNoTransferEncoding) {
1046 // More than 2 dupes.
1047 {
1048 MockRead data_reads[] = {
1049 MockRead("HTTP/1.1 200 OK\r\n"),
1050 MockRead("Content-Length: 5\r\n"),
1051 MockRead("Content-Length: 5\r\n"),
1052 MockRead("Content-Length: 5\r\n\r\n"),
1053 MockRead("Hello"),
1054 };
1055 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1056 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011057 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041058 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1059 EXPECT_EQ("Hello", out.response_data);
1060 }
1061 // HTTP/1.0
1062 {
1063 MockRead data_reads[] = {
1064 MockRead("HTTP/1.0 200 OK\r\n"),
1065 MockRead("Content-Length: 5\r\n"),
1066 MockRead("Content-Length: 5\r\n"),
1067 MockRead("Content-Length: 5\r\n\r\n"),
1068 MockRead("Hello"),
1069 };
1070 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1071 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041073 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1074 EXPECT_EQ("Hello", out.response_data);
1075 }
1076 // 2 dupes and one mismatched.
1077 {
1078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.1 200 OK\r\n"),
1080 MockRead("Content-Length: 10\r\n"),
1081 MockRead("Content-Length: 10\r\n"),
1082 MockRead("Content-Length: 5\r\n\r\n"),
1083 };
1084 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1085 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011086 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041087 }
1088}
1089
bncd16676a2016-07-20 16:23:011090TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001091 MultipleContentLengthHeadersTransferEncoding) {
1092 MockRead data_reads[] = {
1093 MockRead("HTTP/1.1 200 OK\r\n"),
1094 MockRead("Content-Length: 666\r\n"),
1095 MockRead("Content-Length: 1337\r\n"),
1096 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1097 MockRead("5\r\nHello\r\n"),
1098 MockRead("1\r\n"),
1099 MockRead(" \r\n"),
1100 MockRead("5\r\nworld\r\n"),
1101 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061102 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001103 };
1104 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1105 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011106 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001107 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1108 EXPECT_EQ("Hello world", out.response_data);
1109}
1110
[email protected]1628fe92011-10-04 23:04:551111// Next tests deal with http://crbug.com/98895.
1112
1113// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011114TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551115 MockRead data_reads[] = {
1116 MockRead("HTTP/1.1 200 OK\r\n"),
1117 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1118 MockRead("Content-Length: 5\r\n\r\n"),
1119 MockRead("Hello"),
1120 };
1121 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1122 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011123 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551124 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1125 EXPECT_EQ("Hello", out.response_data);
1126}
1127
[email protected]54a9c6e52012-03-21 20:10:591128// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011129TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551130 MockRead data_reads[] = {
1131 MockRead("HTTP/1.1 200 OK\r\n"),
1132 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1133 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1134 MockRead("Content-Length: 5\r\n\r\n"),
1135 MockRead("Hello"),
1136 };
1137 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1138 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011139 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591140 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1141 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551142}
1143
1144// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011145TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551146 MockRead data_reads[] = {
1147 MockRead("HTTP/1.1 200 OK\r\n"),
1148 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1149 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1150 MockRead("Content-Length: 5\r\n\r\n"),
1151 MockRead("Hello"),
1152 };
1153 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1154 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011155 EXPECT_THAT(out.rv,
1156 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551157}
1158
[email protected]54a9c6e52012-03-21 20:10:591159// Checks that two identical Location headers result in no error.
1160// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011161TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551162 MockRead data_reads[] = {
1163 MockRead("HTTP/1.1 302 Redirect\r\n"),
1164 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591165 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551166 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061167 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551168 };
1169
1170 HttpRequestInfo request;
1171 request.method = "GET";
1172 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551173
danakj1fd259a02016-04-16 03:17:091174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161175 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551176
1177 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071178 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551179
[email protected]49639fa2011-12-20 23:22:411180 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551181
tfarina42834112016-09-22 13:38:201182 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011183 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551184
robpercival214763f2016-07-01 23:27:011185 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551186
bnc691fda62016-08-12 00:43:161187 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521188 ASSERT_TRUE(response);
1189 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551190 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1191 std::string url;
1192 EXPECT_TRUE(response->headers->IsRedirect(&url));
1193 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471194 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551195}
1196
[email protected]1628fe92011-10-04 23:04:551197// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011198TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551199 MockRead data_reads[] = {
1200 MockRead("HTTP/1.1 302 Redirect\r\n"),
1201 MockRead("Location: http://good.com/\r\n"),
1202 MockRead("Location: http://evil.com/\r\n"),
1203 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061204 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551205 };
1206 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1207 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011208 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551209}
1210
[email protected]ef0faf2e72009-03-05 23:27:231211// Do a request using the HEAD method. Verify that we don't try to read the
1212// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011213TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421214 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231215 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231216 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231217
danakj1fd259a02016-04-16 03:17:091218 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161219 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091220 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161221 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091222 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1223 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271224
[email protected]ef0faf2e72009-03-05 23:27:231225 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131226 MockWrite("HEAD / HTTP/1.1\r\n"
1227 "Host: www.example.org\r\n"
1228 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231229 };
1230 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231231 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1232 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231233
mmenked39192ee2015-12-09 00:57:231234 // No response body because the test stops reading here.
1235 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231236 };
1237
[email protected]31a2bfe2010-02-09 08:03:391238 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1239 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071240 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231241
[email protected]49639fa2011-12-20 23:22:411242 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231243
tfarina42834112016-09-22 13:38:201244 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011245 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231246
1247 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011248 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231249
bnc691fda62016-08-12 00:43:161250 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521251 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231252
1253 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521254 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231255 EXPECT_EQ(1234, response->headers->GetContentLength());
1256 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471257 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091258 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1259 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231260
1261 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101262 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231263 bool has_server_header = response->headers->EnumerateHeader(
1264 &iter, "Server", &server_header);
1265 EXPECT_TRUE(has_server_header);
1266 EXPECT_EQ("Blah", server_header);
1267
1268 // Reading should give EOF right away, since there is no message body
1269 // (despite non-zero content-length).
1270 std::string response_data;
bnc691fda62016-08-12 00:43:161271 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011272 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231273 EXPECT_EQ("", response_data);
1274}
1275
bncd16676a2016-07-20 16:23:011276TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521278
1279 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351280 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1281 MockRead("hello"),
1282 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1283 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061284 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521285 };
[email protected]31a2bfe2010-02-09 08:03:391286 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071287 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521288
[email protected]0b0bf032010-09-21 18:08:501289 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521290 "hello", "world"
1291 };
1292
1293 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421294 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521295 request.method = "GET";
bncce36dca22015-04-21 22:11:231296 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521297
bnc691fda62016-08-12 00:43:161298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271299
[email protected]49639fa2011-12-20 23:22:411300 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521301
tfarina42834112016-09-22 13:38:201302 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011303 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521304
1305 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011306 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521307
bnc691fda62016-08-12 00:43:161308 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521309 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521310
wezca1070932016-05-26 20:30:521311 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251312 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471313 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521314
1315 std::string response_data;
bnc691fda62016-08-12 00:43:161316 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011317 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251318 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521319 }
1320}
1321
bncd16676a2016-07-20 16:23:011322TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091323 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221324 element_readers.push_back(
ricea2deef682016-09-09 08:04:071325 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221326 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271327
[email protected]1c773ea12009-04-28 19:58:421328 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521329 request.method = "POST";
1330 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271331 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521332
shivanishab9a143952016-09-19 17:23:411333 // Check the upload progress returned before initialization is correct.
1334 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1335 EXPECT_EQ(0u, progress.size());
1336 EXPECT_EQ(0u, progress.position());
1337
danakj1fd259a02016-04-16 03:17:091338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271340
initial.commit586acc5fe2008-07-26 22:42:521341 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351342 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1343 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1344 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061345 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521346 };
[email protected]31a2bfe2010-02-09 08:03:391347 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071348 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521349
[email protected]49639fa2011-12-20 23:22:411350 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521351
tfarina42834112016-09-22 13:38:201352 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521354
1355 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011356 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521357
bnc691fda62016-08-12 00:43:161358 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521359 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521360
wezca1070932016-05-26 20:30:521361 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251362 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521363
1364 std::string response_data;
bnc691fda62016-08-12 00:43:161365 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011366 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251367 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521368}
1369
[email protected]3a2d3662009-03-27 03:49:141370// This test is almost the same as Ignores100 above, but the response contains
1371// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571372// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011373TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421374 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141375 request.method = "GET";
1376 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141377
danakj1fd259a02016-04-16 03:17:091378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161379 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271380
[email protected]3a2d3662009-03-27 03:49:141381 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571382 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1383 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141384 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061385 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141386 };
[email protected]31a2bfe2010-02-09 08:03:391387 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071388 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141389
[email protected]49639fa2011-12-20 23:22:411390 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141391
tfarina42834112016-09-22 13:38:201392 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141394
1395 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011396 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141397
bnc691fda62016-08-12 00:43:161398 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521399 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141400
wezca1070932016-05-26 20:30:521401 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141402 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1403
1404 std::string response_data;
bnc691fda62016-08-12 00:43:161405 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011406 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141407 EXPECT_EQ("hello world", response_data);
1408}
1409
bncd16676a2016-07-20 16:23:011410TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081411 HttpRequestInfo request;
1412 request.method = "POST";
1413 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081414
danakj1fd259a02016-04-16 03:17:091415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161416 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081417
1418 MockRead data_reads[] = {
1419 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1420 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381421 };
zmo9528c9f42015-08-04 22:12:081422 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1423 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381424
zmo9528c9f42015-08-04 22:12:081425 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381426
tfarina42834112016-09-22 13:38:201427 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011428 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381429
zmo9528c9f42015-08-04 22:12:081430 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011431 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381432
zmo9528c9f42015-08-04 22:12:081433 std::string response_data;
bnc691fda62016-08-12 00:43:161434 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011435 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081436 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381437}
1438
bncd16676a2016-07-20 16:23:011439TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381440 HttpRequestInfo request;
1441 request.method = "POST";
1442 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381443
danakj1fd259a02016-04-16 03:17:091444 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161445 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271446
[email protected]ee9410e72010-01-07 01:42:381447 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061448 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381449 };
[email protected]31a2bfe2010-02-09 08:03:391450 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071451 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381452
[email protected]49639fa2011-12-20 23:22:411453 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381454
tfarina42834112016-09-22 13:38:201455 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381457
1458 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011459 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381460}
1461
[email protected]23e482282013-06-14 16:08:021462void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511463 const MockWrite* write_failure,
1464 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421465 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521466 request.method = "GET";
1467 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521468
vishal.b62985ca92015-04-17 08:45:511469 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071470 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271472
[email protected]202965992011-12-07 23:04:511473 // Written data for successfully sending both requests.
1474 MockWrite data1_writes[] = {
1475 MockWrite("GET / HTTP/1.1\r\n"
1476 "Host: www.foo.com\r\n"
1477 "Connection: keep-alive\r\n\r\n"),
1478 MockWrite("GET / HTTP/1.1\r\n"
1479 "Host: www.foo.com\r\n"
1480 "Connection: keep-alive\r\n\r\n")
1481 };
1482
1483 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521484 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351485 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1486 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061487 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521488 };
[email protected]202965992011-12-07 23:04:511489
1490 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491491 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511492 data1_writes[1] = *write_failure;
1493 } else {
1494 ASSERT_TRUE(read_failure);
1495 data1_reads[2] = *read_failure;
1496 }
1497
1498 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1499 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071500 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521501
1502 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351503 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1504 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061505 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521506 };
[email protected]31a2bfe2010-02-09 08:03:391507 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071508 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521509
thestig9d3bb0c2015-01-24 00:49:511510 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521511 "hello", "world"
1512 };
1513
mikecironef22f9812016-10-04 03:40:191514 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521515 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411516 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521517
bnc691fda62016-08-12 00:43:161518 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521519
tfarina42834112016-09-22 13:38:201520 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011521 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521522
1523 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011524 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521525
[email protected]58e32bb2013-01-21 18:23:251526 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161527 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251528 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1529 if (i == 0) {
1530 first_socket_log_id = load_timing_info.socket_log_id;
1531 } else {
1532 // The second request should be using a new socket.
1533 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1534 }
1535
bnc691fda62016-08-12 00:43:161536 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521537 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521538
wezca1070932016-05-26 20:30:521539 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471540 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251541 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521542
1543 std::string response_data;
bnc691fda62016-08-12 00:43:161544 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011545 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251546 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521547 }
1548}
[email protected]3d2a59b2008-09-26 19:44:251549
[email protected]a34f61ee2014-03-18 20:59:491550void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1551 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101552 const MockRead* read_failure,
1553 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491554 HttpRequestInfo request;
1555 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101556 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491557
vishal.b62985ca92015-04-17 08:45:511558 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491559 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091560 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491561
[email protected]09356c652014-03-25 15:36:101562 SSLSocketDataProvider ssl1(ASYNC, OK);
1563 SSLSocketDataProvider ssl2(ASYNC, OK);
1564 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361565 ssl1.next_proto = kProtoHTTP2;
1566 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101567 }
1568 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491570
[email protected]09356c652014-03-25 15:36:101571 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411572 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491573 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411574 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151575 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411576 SpdySerializedFrame spdy_data(
1577 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491578
[email protected]09356c652014-03-25 15:36:101579 // HTTP/1.1 versions of the request and response.
1580 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1581 "Host: www.foo.com\r\n"
1582 "Connection: keep-alive\r\n\r\n";
1583 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1584 const char kHttpData[] = "hello";
1585
1586 std::vector<MockRead> data1_reads;
1587 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491588 if (write_failure) {
1589 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101590 data1_writes.push_back(*write_failure);
1591 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491592 } else {
1593 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101594 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411595 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101596 } else {
1597 data1_writes.push_back(MockWrite(kHttpRequest));
1598 }
1599 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491600 }
1601
[email protected]09356c652014-03-25 15:36:101602 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1603 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491604 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1605
[email protected]09356c652014-03-25 15:36:101606 std::vector<MockRead> data2_reads;
1607 std::vector<MockWrite> data2_writes;
1608
1609 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411610 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101611
bncdf80d44fd2016-07-15 20:27:411612 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1613 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101614 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1615 } else {
1616 data2_writes.push_back(
1617 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1618
1619 data2_reads.push_back(
1620 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1621 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1622 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1623 }
rch8e6c6c42015-05-01 14:05:131624 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1625 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491626 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1627
1628 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591629 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491630 // Wait for the preconnect to complete.
1631 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1632 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101633 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491634
1635 // Make the request.
1636 TestCompletionCallback callback;
1637
bnc691fda62016-08-12 00:43:161638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491639
tfarina42834112016-09-22 13:38:201640 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491642
1643 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011644 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491645
1646 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161647 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101648 TestLoadTimingNotReused(
1649 load_timing_info,
1650 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491651
bnc691fda62016-08-12 00:43:161652 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521653 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491654
wezca1070932016-05-26 20:30:521655 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021656 if (response->was_fetched_via_spdy) {
1657 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1658 } else {
1659 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1660 }
[email protected]a34f61ee2014-03-18 20:59:491661
1662 std::string response_data;
bnc691fda62016-08-12 00:43:161663 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011664 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101665 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491666}
1667
bncd16676a2016-07-20 16:23:011668TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061669 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511670 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1671}
1672
bncd16676a2016-07-20 16:23:011673TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061674 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511675 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251676}
1677
bncd16676a2016-07-20 16:23:011678TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061679 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511680 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251681}
1682
[email protected]d58ceea82014-06-04 10:55:541683// Make sure that on a 408 response (Request Timeout), the request is retried,
1684// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011685TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541686 MockRead read_failure(SYNCHRONOUS,
1687 "HTTP/1.1 408 Request Timeout\r\n"
1688 "Connection: Keep-Alive\r\n"
1689 "Content-Length: 6\r\n\r\n"
1690 "Pickle");
1691 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1692}
1693
bncd16676a2016-07-20 16:23:011694TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491695 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101696 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491697}
1698
bncd16676a2016-07-20 16:23:011699TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491700 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101701 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491702}
1703
bncd16676a2016-07-20 16:23:011704TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491705 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101706 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1707}
1708
bncd16676a2016-07-20 16:23:011709TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101710 MockRead read_failure(ASYNC, OK); // EOF
1711 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1712}
1713
[email protected]d58ceea82014-06-04 10:55:541714// Make sure that on a 408 response (Request Timeout), the request is retried,
1715// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011716TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541717 MockRead read_failure(SYNCHRONOUS,
1718 "HTTP/1.1 408 Request Timeout\r\n"
1719 "Connection: Keep-Alive\r\n"
1720 "Content-Length: 6\r\n\r\n"
1721 "Pickle");
1722 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1723 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1724}
1725
bncd16676a2016-07-20 16:23:011726TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101727 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1728 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1729}
1730
bncd16676a2016-07-20 16:23:011731TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101732 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1733 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1734}
1735
bncd16676a2016-07-20 16:23:011736TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101737 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1738 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1739}
1740
bncd16676a2016-07-20 16:23:011741TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101742 MockRead read_failure(ASYNC, OK); // EOF
1743 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491744}
1745
bncd16676a2016-07-20 16:23:011746TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421747 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251748 request.method = "GET";
bncce36dca22015-04-21 22:11:231749 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251750
danakj1fd259a02016-04-16 03:17:091751 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161752 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271753
[email protected]3d2a59b2008-09-26 19:44:251754 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061755 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351756 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1757 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061758 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251759 };
[email protected]31a2bfe2010-02-09 08:03:391760 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071761 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251762
[email protected]49639fa2011-12-20 23:22:411763 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251764
tfarina42834112016-09-22 13:38:201765 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011766 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251767
1768 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011769 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591770
1771 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161772 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591773 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251774}
1775
1776// What do various browsers do when the server closes a non-keepalive
1777// connection without sending any response header or body?
1778//
1779// IE7: error page
1780// Safari 3.1.2 (Windows): error page
1781// Firefox 3.0.1: blank page
1782// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421783// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1784// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011785TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251786 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061787 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351788 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1789 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061790 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251791 };
[email protected]31a2bfe2010-02-09 08:03:391792 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1793 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011794 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251795}
[email protected]1826a402014-01-08 15:40:481796
[email protected]7a5378b2012-11-04 03:25:171797// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1798// tests. There was a bug causing HttpNetworkTransaction to hang in the
1799// destructor in such situations.
1800// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011801TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171802 HttpRequestInfo request;
1803 request.method = "GET";
bncce36dca22015-04-21 22:11:231804 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171805
danakj1fd259a02016-04-16 03:17:091806 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581807 auto trans =
1808 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171809
1810 MockRead data_reads[] = {
1811 MockRead("HTTP/1.0 200 OK\r\n"),
1812 MockRead("Connection: keep-alive\r\n"),
1813 MockRead("Content-Length: 100\r\n\r\n"),
1814 MockRead("hello"),
1815 MockRead(SYNCHRONOUS, 0),
1816 };
1817 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071818 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171819
1820 TestCompletionCallback callback;
1821
tfarina42834112016-09-22 13:38:201822 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171824
1825 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011826 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171827
1828 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501829 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171830 if (rv == ERR_IO_PENDING)
1831 rv = callback.WaitForResult();
1832 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501833 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011834 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171835
1836 trans.reset();
fdoray92e35a72016-06-10 15:54:551837 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171838 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1839}
1840
bncd16676a2016-07-20 16:23:011841TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171842 HttpRequestInfo request;
1843 request.method = "GET";
bncce36dca22015-04-21 22:11:231844 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171845
danakj1fd259a02016-04-16 03:17:091846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581847 auto trans =
1848 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171849
1850 MockRead data_reads[] = {
1851 MockRead("HTTP/1.0 200 OK\r\n"),
1852 MockRead("Connection: keep-alive\r\n"),
1853 MockRead("Content-Length: 100\r\n\r\n"),
1854 MockRead(SYNCHRONOUS, 0),
1855 };
1856 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071857 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171858
1859 TestCompletionCallback callback;
1860
tfarina42834112016-09-22 13:38:201861 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011862 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171863
1864 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011865 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171866
1867 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501868 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171869 if (rv == ERR_IO_PENDING)
1870 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011871 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171872
1873 trans.reset();
fdoray92e35a72016-06-10 15:54:551874 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171875 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1876}
1877
[email protected]0b0bf032010-09-21 18:08:501878// Test that we correctly reuse a keep-alive connection after not explicitly
1879// reading the body.
bncd16676a2016-07-20 16:23:011880TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131881 HttpRequestInfo request;
1882 request.method = "GET";
1883 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131884
vishal.b62985ca92015-04-17 08:45:511885 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071886 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271888
mmenkecc2298e2015-12-07 18:20:181889 const char* request_data =
1890 "GET / HTTP/1.1\r\n"
1891 "Host: www.foo.com\r\n"
1892 "Connection: keep-alive\r\n\r\n";
1893 MockWrite data_writes[] = {
1894 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1895 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1896 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1897 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1898 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1899 };
1900
[email protected]0b0bf032010-09-21 18:08:501901 // Note that because all these reads happen in the same
1902 // StaticSocketDataProvider, it shows that the same socket is being reused for
1903 // all transactions.
mmenkecc2298e2015-12-07 18:20:181904 MockRead data_reads[] = {
1905 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1906 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1907 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1908 MockRead(ASYNC, 7,
1909 "HTTP/1.1 302 Found\r\n"
1910 "Content-Length: 0\r\n\r\n"),
1911 MockRead(ASYNC, 9,
1912 "HTTP/1.1 302 Found\r\n"
1913 "Content-Length: 5\r\n\r\n"
1914 "hello"),
1915 MockRead(ASYNC, 11,
1916 "HTTP/1.1 301 Moved Permanently\r\n"
1917 "Content-Length: 0\r\n\r\n"),
1918 MockRead(ASYNC, 13,
1919 "HTTP/1.1 301 Moved Permanently\r\n"
1920 "Content-Length: 5\r\n\r\n"
1921 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131922
mmenkecc2298e2015-12-07 18:20:181923 // In the next two rounds, IsConnectedAndIdle returns false, due to
1924 // the set_busy_before_sync_reads(true) call, while the
1925 // HttpNetworkTransaction is being shut down, but the socket is still
1926 // reuseable. See http://crbug.com/544255.
1927 MockRead(ASYNC, 15,
1928 "HTTP/1.1 200 Hunky-Dory\r\n"
1929 "Content-Length: 5\r\n\r\n"),
1930 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131931
mmenkecc2298e2015-12-07 18:20:181932 MockRead(ASYNC, 18,
1933 "HTTP/1.1 200 Hunky-Dory\r\n"
1934 "Content-Length: 5\r\n\r\n"
1935 "he"),
1936 MockRead(SYNCHRONOUS, 19, "llo"),
1937
1938 // The body of the final request is actually read.
1939 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1940 MockRead(ASYNC, 22, "hello"),
1941 };
1942 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1943 arraysize(data_writes));
1944 data.set_busy_before_sync_reads(true);
1945 session_deps_.socket_factory->AddSocketDataProvider(&data);
1946
1947 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501948 std::string response_lines[kNumUnreadBodies];
1949
mikecironef22f9812016-10-04 03:40:191950 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181951 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411952 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131953
bnc87dcefc2017-05-25 12:47:581954 auto trans = base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
1955 session.get());
[email protected]fc31d6a42010-06-24 18:05:131956
tfarina42834112016-09-22 13:38:201957 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011958 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131959
[email protected]58e32bb2013-01-21 18:23:251960 LoadTimingInfo load_timing_info;
1961 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1962 if (i == 0) {
1963 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1964 first_socket_log_id = load_timing_info.socket_log_id;
1965 } else {
1966 TestLoadTimingReused(load_timing_info);
1967 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1968 }
1969
[email protected]fc31d6a42010-06-24 18:05:131970 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181971 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131972
mmenkecc2298e2015-12-07 18:20:181973 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501974 response_lines[i] = response->headers->GetStatusLine();
1975
mmenkecc2298e2015-12-07 18:20:181976 // Delete the transaction without reading the response bodies. Then spin
1977 // the message loop, so the response bodies are drained.
1978 trans.reset();
1979 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131980 }
[email protected]0b0bf032010-09-21 18:08:501981
1982 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181983 "HTTP/1.1 204 No Content",
1984 "HTTP/1.1 205 Reset Content",
1985 "HTTP/1.1 304 Not Modified",
1986 "HTTP/1.1 302 Found",
1987 "HTTP/1.1 302 Found",
1988 "HTTP/1.1 301 Moved Permanently",
1989 "HTTP/1.1 301 Moved Permanently",
1990 "HTTP/1.1 200 Hunky-Dory",
1991 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501992 };
1993
mostynb91e0da982015-01-20 19:17:271994 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1995 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501996
1997 for (int i = 0; i < kNumUnreadBodies; ++i)
1998 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1999
[email protected]49639fa2011-12-20 23:22:412000 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162001 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202002 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012003 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162004 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182005 ASSERT_TRUE(response);
2006 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502007 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2008 std::string response_data;
bnc691fda62016-08-12 00:43:162009 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012010 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502011 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132012}
2013
mmenke5f94fda2016-06-02 20:54:132014// Sockets that receive extra data after a response is complete should not be
2015// reused.
bncd16676a2016-07-20 16:23:012016TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2018 MockWrite data_writes1[] = {
2019 MockWrite("HEAD / HTTP/1.1\r\n"
2020 "Host: www.borked.com\r\n"
2021 "Connection: keep-alive\r\n\r\n"),
2022 };
2023
2024 MockRead data_reads1[] = {
2025 MockRead("HTTP/1.1 200 OK\r\n"
2026 "Connection: keep-alive\r\n"
2027 "Content-Length: 22\r\n\r\n"
2028 "This server is borked."),
2029 };
2030
2031 MockWrite data_writes2[] = {
2032 MockWrite("GET /foo HTTP/1.1\r\n"
2033 "Host: www.borked.com\r\n"
2034 "Connection: keep-alive\r\n\r\n"),
2035 };
2036
2037 MockRead data_reads2[] = {
2038 MockRead("HTTP/1.1 200 OK\r\n"
2039 "Content-Length: 3\r\n\r\n"
2040 "foo"),
2041 };
2042 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2043 data_writes1, arraysize(data_writes1));
2044 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2045 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2046 data_writes2, arraysize(data_writes2));
2047 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2048
2049 TestCompletionCallback callback;
2050 HttpRequestInfo request1;
2051 request1.method = "HEAD";
2052 request1.url = GURL("http://www.borked.com/");
2053
bnc87dcefc2017-05-25 12:47:582054 auto trans1 =
2055 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202056 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012057 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132058
2059 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2060 ASSERT_TRUE(response1);
2061 ASSERT_TRUE(response1->headers);
2062 EXPECT_EQ(200, response1->headers->response_code());
2063 EXPECT_TRUE(response1->headers->IsKeepAlive());
2064
2065 std::string response_data1;
robpercival214763f2016-07-01 23:27:012066 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132067 EXPECT_EQ("", response_data1);
2068 // Deleting the transaction attempts to release the socket back into the
2069 // socket pool.
2070 trans1.reset();
2071
2072 HttpRequestInfo request2;
2073 request2.method = "GET";
2074 request2.url = GURL("http://www.borked.com/foo");
2075
bnc87dcefc2017-05-25 12:47:582076 auto trans2 =
2077 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202078 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012079 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132080
2081 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2082 ASSERT_TRUE(response2);
2083 ASSERT_TRUE(response2->headers);
2084 EXPECT_EQ(200, response2->headers->response_code());
2085
2086 std::string response_data2;
robpercival214763f2016-07-01 23:27:012087 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132088 EXPECT_EQ("foo", response_data2);
2089}
2090
bncd16676a2016-07-20 16:23:012091TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132092 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2093 MockWrite data_writes1[] = {
2094 MockWrite("GET / HTTP/1.1\r\n"
2095 "Host: www.borked.com\r\n"
2096 "Connection: keep-alive\r\n\r\n"),
2097 };
2098
2099 MockRead data_reads1[] = {
2100 MockRead("HTTP/1.1 200 OK\r\n"
2101 "Connection: keep-alive\r\n"
2102 "Content-Length: 22\r\n\r\n"
2103 "This server is borked."
2104 "Bonus data!"),
2105 };
2106
2107 MockWrite data_writes2[] = {
2108 MockWrite("GET /foo HTTP/1.1\r\n"
2109 "Host: www.borked.com\r\n"
2110 "Connection: keep-alive\r\n\r\n"),
2111 };
2112
2113 MockRead data_reads2[] = {
2114 MockRead("HTTP/1.1 200 OK\r\n"
2115 "Content-Length: 3\r\n\r\n"
2116 "foo"),
2117 };
2118 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2119 data_writes1, arraysize(data_writes1));
2120 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2121 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2122 data_writes2, arraysize(data_writes2));
2123 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2124
2125 TestCompletionCallback callback;
2126 HttpRequestInfo request1;
2127 request1.method = "GET";
2128 request1.url = GURL("http://www.borked.com/");
2129
bnc87dcefc2017-05-25 12:47:582130 auto trans1 =
2131 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202132 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012133 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132134
2135 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2136 ASSERT_TRUE(response1);
2137 ASSERT_TRUE(response1->headers);
2138 EXPECT_EQ(200, response1->headers->response_code());
2139 EXPECT_TRUE(response1->headers->IsKeepAlive());
2140
2141 std::string response_data1;
robpercival214763f2016-07-01 23:27:012142 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132143 EXPECT_EQ("This server is borked.", response_data1);
2144 // Deleting the transaction attempts to release the socket back into the
2145 // socket pool.
2146 trans1.reset();
2147
2148 HttpRequestInfo request2;
2149 request2.method = "GET";
2150 request2.url = GURL("http://www.borked.com/foo");
2151
bnc87dcefc2017-05-25 12:47:582152 auto trans2 =
2153 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202154 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012155 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132156
2157 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2158 ASSERT_TRUE(response2);
2159 ASSERT_TRUE(response2->headers);
2160 EXPECT_EQ(200, response2->headers->response_code());
2161
2162 std::string response_data2;
robpercival214763f2016-07-01 23:27:012163 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132164 EXPECT_EQ("foo", response_data2);
2165}
2166
bncd16676a2016-07-20 16:23:012167TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132168 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2169 MockWrite data_writes1[] = {
2170 MockWrite("GET / HTTP/1.1\r\n"
2171 "Host: www.borked.com\r\n"
2172 "Connection: keep-alive\r\n\r\n"),
2173 };
2174
2175 MockRead data_reads1[] = {
2176 MockRead("HTTP/1.1 200 OK\r\n"
2177 "Connection: keep-alive\r\n"
2178 "Transfer-Encoding: chunked\r\n\r\n"),
2179 MockRead("16\r\nThis server is borked.\r\n"),
2180 MockRead("0\r\n\r\nBonus data!"),
2181 };
2182
2183 MockWrite data_writes2[] = {
2184 MockWrite("GET /foo HTTP/1.1\r\n"
2185 "Host: www.borked.com\r\n"
2186 "Connection: keep-alive\r\n\r\n"),
2187 };
2188
2189 MockRead data_reads2[] = {
2190 MockRead("HTTP/1.1 200 OK\r\n"
2191 "Content-Length: 3\r\n\r\n"
2192 "foo"),
2193 };
2194 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2195 data_writes1, arraysize(data_writes1));
2196 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2197 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2198 data_writes2, arraysize(data_writes2));
2199 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2200
2201 TestCompletionCallback callback;
2202 HttpRequestInfo request1;
2203 request1.method = "GET";
2204 request1.url = GURL("http://www.borked.com/");
2205
bnc87dcefc2017-05-25 12:47:582206 auto trans1 =
2207 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202208 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012209 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132210
2211 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2212 ASSERT_TRUE(response1);
2213 ASSERT_TRUE(response1->headers);
2214 EXPECT_EQ(200, response1->headers->response_code());
2215 EXPECT_TRUE(response1->headers->IsKeepAlive());
2216
2217 std::string response_data1;
robpercival214763f2016-07-01 23:27:012218 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132219 EXPECT_EQ("This server is borked.", response_data1);
2220 // Deleting the transaction attempts to release the socket back into the
2221 // socket pool.
2222 trans1.reset();
2223
2224 HttpRequestInfo request2;
2225 request2.method = "GET";
2226 request2.url = GURL("http://www.borked.com/foo");
2227
bnc87dcefc2017-05-25 12:47:582228 auto trans2 =
2229 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202230 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012231 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132232
2233 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2234 ASSERT_TRUE(response2);
2235 ASSERT_TRUE(response2->headers);
2236 EXPECT_EQ(200, response2->headers->response_code());
2237
2238 std::string response_data2;
robpercival214763f2016-07-01 23:27:012239 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132240 EXPECT_EQ("foo", response_data2);
2241}
2242
2243// This is a little different from the others - it tests the case that the
2244// HttpStreamParser doesn't know if there's extra data on a socket or not when
2245// the HttpNetworkTransaction is torn down, because the response body hasn't
2246// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012247TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132248 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2249 MockWrite data_writes1[] = {
2250 MockWrite("GET / HTTP/1.1\r\n"
2251 "Host: www.borked.com\r\n"
2252 "Connection: keep-alive\r\n\r\n"),
2253 };
2254
2255 MockRead data_reads1[] = {
2256 MockRead("HTTP/1.1 200 OK\r\n"
2257 "Connection: keep-alive\r\n"
2258 "Transfer-Encoding: chunked\r\n\r\n"),
2259 MockRead("16\r\nThis server is borked.\r\n"),
2260 MockRead("0\r\n\r\nBonus data!"),
2261 };
2262 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2263 data_writes1, arraysize(data_writes1));
2264 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2265
2266 TestCompletionCallback callback;
2267 HttpRequestInfo request1;
2268 request1.method = "GET";
2269 request1.url = GURL("http://www.borked.com/");
2270
bnc87dcefc2017-05-25 12:47:582271 auto trans =
2272 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
2273 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012274 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132275
bnc87dcefc2017-05-25 12:47:582276 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132277 ASSERT_TRUE(response1);
2278 ASSERT_TRUE(response1->headers);
2279 EXPECT_EQ(200, response1->headers->response_code());
2280 EXPECT_TRUE(response1->headers->IsKeepAlive());
2281
2282 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2283 // response body.
bnc87dcefc2017-05-25 12:47:582284 trans.reset();
mmenke5f94fda2016-06-02 20:54:132285
2286 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2287 // socket can't be reused, rather than returning it to the socket pool.
2288 base::RunLoop().RunUntilIdle();
2289
2290 // There should be no idle sockets in the pool.
2291 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2292}
2293
[email protected]038e9a32008-10-08 22:40:162294// Test the request-challenge-retry sequence for basic auth.
2295// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012296TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422297 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162298 request.method = "GET";
bncce36dca22015-04-21 22:11:232299 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162300
vishal.b62985ca92015-04-17 08:45:512301 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072302 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092303 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272305
[email protected]f9ee6b52008-11-08 06:46:232306 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232307 MockWrite(
2308 "GET / HTTP/1.1\r\n"
2309 "Host: www.example.org\r\n"
2310 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232311 };
2312
[email protected]038e9a32008-10-08 22:40:162313 MockRead data_reads1[] = {
2314 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2315 // Give a couple authenticate options (only the middle one is actually
2316 // supported).
[email protected]22927ad2009-09-21 19:56:192317 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162318 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2319 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2320 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2321 // Large content-length -- won't matter, as connection will be reset.
2322 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062323 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162324 };
2325
2326 // After calling trans->RestartWithAuth(), this is the request we should
2327 // be issuing -- the final header line contains the credentials.
2328 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232329 MockWrite(
2330 "GET / HTTP/1.1\r\n"
2331 "Host: www.example.org\r\n"
2332 "Connection: keep-alive\r\n"
2333 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162334 };
2335
2336 // Lastly, the server responds with the actual content.
2337 MockRead data_reads2[] = {
2338 MockRead("HTTP/1.0 200 OK\r\n"),
2339 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2340 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062341 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162342 };
2343
[email protected]31a2bfe2010-02-09 08:03:392344 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2345 data_writes1, arraysize(data_writes1));
2346 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2347 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072348 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2349 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162350
[email protected]49639fa2011-12-20 23:22:412351 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162352
tfarina42834112016-09-22 13:38:202353 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162355
2356 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012357 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162358
[email protected]58e32bb2013-01-21 18:23:252359 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162360 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252361 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2362
sclittlefb249892015-09-10 21:33:222363 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162364 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222365 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162366 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192367
bnc691fda62016-08-12 00:43:162368 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522369 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042370 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162371
[email protected]49639fa2011-12-20 23:22:412372 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162373
bnc691fda62016-08-12 00:43:162374 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162376
2377 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012378 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162379
[email protected]58e32bb2013-01-21 18:23:252380 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162381 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252382 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2383 // The load timing after restart should have a new socket ID, and times after
2384 // those of the first load timing.
2385 EXPECT_LE(load_timing_info1.receive_headers_end,
2386 load_timing_info2.connect_timing.connect_start);
2387 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2388
sclittlefb249892015-09-10 21:33:222389 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162390 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222391 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162392 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192393
bnc691fda62016-08-12 00:43:162394 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522395 ASSERT_TRUE(response);
2396 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162397 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162398}
2399
ttuttled9dbc652015-09-29 20:00:592400// Test the request-challenge-retry sequence for basic auth.
2401// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012402TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592403 HttpRequestInfo request;
2404 request.method = "GET";
2405 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592406
2407 TestNetLog log;
2408 MockHostResolver* resolver = new MockHostResolver();
2409 session_deps_.net_log = &log;
2410 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092411 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162412 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592413
2414 resolver->rules()->ClearRules();
2415 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2416
2417 MockWrite data_writes1[] = {
2418 MockWrite("GET / HTTP/1.1\r\n"
2419 "Host: www.example.org\r\n"
2420 "Connection: keep-alive\r\n\r\n"),
2421 };
2422
2423 MockRead data_reads1[] = {
2424 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2425 // Give a couple authenticate options (only the middle one is actually
2426 // supported).
2427 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2428 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2429 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2430 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2431 // Large content-length -- won't matter, as connection will be reset.
2432 MockRead("Content-Length: 10000\r\n\r\n"),
2433 MockRead(SYNCHRONOUS, ERR_FAILED),
2434 };
2435
2436 // After calling trans->RestartWithAuth(), this is the request we should
2437 // be issuing -- the final header line contains the credentials.
2438 MockWrite data_writes2[] = {
2439 MockWrite("GET / HTTP/1.1\r\n"
2440 "Host: www.example.org\r\n"
2441 "Connection: keep-alive\r\n"
2442 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2443 };
2444
2445 // Lastly, the server responds with the actual content.
2446 MockRead data_reads2[] = {
2447 MockRead("HTTP/1.0 200 OK\r\n"),
2448 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2449 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2450 };
2451
2452 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2453 data_writes1, arraysize(data_writes1));
2454 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2455 data_writes2, arraysize(data_writes2));
2456 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2457 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2458
2459 TestCompletionCallback callback1;
2460
bnc691fda62016-08-12 00:43:162461 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202462 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592463
2464 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162465 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592466 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2467
2468 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162469 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592470 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162471 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592472
bnc691fda62016-08-12 00:43:162473 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592474 ASSERT_TRUE(response);
2475 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2476
2477 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162478 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592479 ASSERT_FALSE(endpoint.address().empty());
2480 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2481
2482 resolver->rules()->ClearRules();
2483 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2484
2485 TestCompletionCallback callback2;
2486
bnc691fda62016-08-12 00:43:162487 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592488 AuthCredentials(kFoo, kBar), callback2.callback())));
2489
2490 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162491 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592492 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2493 // The load timing after restart should have a new socket ID, and times after
2494 // those of the first load timing.
2495 EXPECT_LE(load_timing_info1.receive_headers_end,
2496 load_timing_info2.connect_timing.connect_start);
2497 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2498
2499 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162500 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592501 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162502 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592503
bnc691fda62016-08-12 00:43:162504 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592505 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522506 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592507 EXPECT_EQ(100, response->headers->GetContentLength());
2508
bnc691fda62016-08-12 00:43:162509 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592510 ASSERT_FALSE(endpoint.address().empty());
2511 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2512}
2513
bncd16676a2016-07-20 16:23:012514TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462515 HttpRequestInfo request;
2516 request.method = "GET";
bncce36dca22015-04-21 22:11:232517 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292518 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462519
danakj1fd259a02016-04-16 03:17:092520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162521 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272522
[email protected]861fcd52009-08-26 02:33:462523 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232524 MockWrite(
2525 "GET / HTTP/1.1\r\n"
2526 "Host: www.example.org\r\n"
2527 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462528 };
2529
2530 MockRead data_reads[] = {
2531 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2532 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2534 // Large content-length -- won't matter, as connection will be reset.
2535 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062536 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462537 };
2538
[email protected]31a2bfe2010-02-09 08:03:392539 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2540 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072541 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412542 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462543
tfarina42834112016-09-22 13:38:202544 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012545 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462546
2547 rv = callback.WaitForResult();
2548 EXPECT_EQ(0, rv);
2549
sclittlefb249892015-09-10 21:33:222550 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162551 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222552 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162553 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192554
bnc691fda62016-08-12 00:43:162555 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522556 ASSERT_TRUE(response);
2557 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462558}
2559
[email protected]2d2697f92009-02-18 21:00:322560// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2561// connection.
bncd16676a2016-07-20 16:23:012562TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182563 // On the second pass, the body read of the auth challenge is synchronous, so
2564 // IsConnectedAndIdle returns false. The socket should still be drained and
2565 // reused. See http://crbug.com/544255.
2566 for (int i = 0; i < 2; ++i) {
2567 HttpRequestInfo request;
2568 request.method = "GET";
2569 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322570
mmenkecc2298e2015-12-07 18:20:182571 TestNetLog log;
2572 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092573 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272574
mmenkecc2298e2015-12-07 18:20:182575 MockWrite data_writes[] = {
2576 MockWrite(ASYNC, 0,
2577 "GET / HTTP/1.1\r\n"
2578 "Host: www.example.org\r\n"
2579 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322580
bnc691fda62016-08-12 00:43:162581 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182582 // be issuing -- the final header line contains the credentials.
2583 MockWrite(ASYNC, 6,
2584 "GET / HTTP/1.1\r\n"
2585 "Host: www.example.org\r\n"
2586 "Connection: keep-alive\r\n"
2587 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2588 };
[email protected]2d2697f92009-02-18 21:00:322589
mmenkecc2298e2015-12-07 18:20:182590 MockRead data_reads[] = {
2591 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2592 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2593 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2594 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2595 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322596
mmenkecc2298e2015-12-07 18:20:182597 // Lastly, the server responds with the actual content.
2598 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2599 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2600 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2601 MockRead(ASYNC, 10, "Hello"),
2602 };
[email protected]2d2697f92009-02-18 21:00:322603
mmenkecc2298e2015-12-07 18:20:182604 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2605 arraysize(data_writes));
2606 data.set_busy_before_sync_reads(true);
2607 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462608
mmenkecc2298e2015-12-07 18:20:182609 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322610
bnc691fda62016-08-12 00:43:162611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202612 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012613 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322614
mmenkecc2298e2015-12-07 18:20:182615 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162616 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182617 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322618
bnc691fda62016-08-12 00:43:162619 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182620 ASSERT_TRUE(response);
2621 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322622
mmenkecc2298e2015-12-07 18:20:182623 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252624
bnc691fda62016-08-12 00:43:162625 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2626 callback2.callback());
robpercival214763f2016-07-01 23:27:012627 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322628
mmenkecc2298e2015-12-07 18:20:182629 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162630 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182631 TestLoadTimingReused(load_timing_info2);
2632 // The load timing after restart should have the same socket ID, and times
2633 // those of the first load timing.
2634 EXPECT_LE(load_timing_info1.receive_headers_end,
2635 load_timing_info2.send_start);
2636 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322637
bnc691fda62016-08-12 00:43:162638 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182639 ASSERT_TRUE(response);
2640 EXPECT_FALSE(response->auth_challenge);
2641 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322642
mmenkecc2298e2015-12-07 18:20:182643 std::string response_data;
bnc691fda62016-08-12 00:43:162644 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322645
mmenkecc2298e2015-12-07 18:20:182646 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162647 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182648 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162649 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182650 }
[email protected]2d2697f92009-02-18 21:00:322651}
2652
2653// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2654// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012655TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422656 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322657 request.method = "GET";
bncce36dca22015-04-21 22:11:232658 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322659
danakj1fd259a02016-04-16 03:17:092660 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272661
[email protected]2d2697f92009-02-18 21:00:322662 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162663 MockWrite("GET / HTTP/1.1\r\n"
2664 "Host: www.example.org\r\n"
2665 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322666
bnc691fda62016-08-12 00:43:162667 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232668 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162669 MockWrite("GET / HTTP/1.1\r\n"
2670 "Host: www.example.org\r\n"
2671 "Connection: keep-alive\r\n"
2672 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322673 };
2674
[email protected]2d2697f92009-02-18 21:00:322675 MockRead data_reads1[] = {
2676 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2677 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312678 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322679
2680 // Lastly, the server responds with the actual content.
2681 MockRead("HTTP/1.1 200 OK\r\n"),
2682 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502683 MockRead("Content-Length: 5\r\n\r\n"),
2684 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322685 };
2686
[email protected]2d0a4f92011-05-05 16:38:462687 // An incorrect reconnect would cause this to be read.
2688 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062689 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462690 };
2691
[email protected]31a2bfe2010-02-09 08:03:392692 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2693 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462694 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2695 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072696 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2697 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322698
[email protected]49639fa2011-12-20 23:22:412699 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322700
bnc691fda62016-08-12 00:43:162701 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202702 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322704
2705 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012706 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322707
bnc691fda62016-08-12 00:43:162708 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522709 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042710 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322711
[email protected]49639fa2011-12-20 23:22:412712 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322713
bnc691fda62016-08-12 00:43:162714 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322716
2717 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012718 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322719
bnc691fda62016-08-12 00:43:162720 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522721 ASSERT_TRUE(response);
2722 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502723 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322724}
2725
2726// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2727// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012728TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422729 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322730 request.method = "GET";
bncce36dca22015-04-21 22:11:232731 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322732
danakj1fd259a02016-04-16 03:17:092733 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272734
[email protected]2d2697f92009-02-18 21:00:322735 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162736 MockWrite("GET / HTTP/1.1\r\n"
2737 "Host: www.example.org\r\n"
2738 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322739
bnc691fda62016-08-12 00:43:162740 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232741 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162742 MockWrite("GET / HTTP/1.1\r\n"
2743 "Host: www.example.org\r\n"
2744 "Connection: keep-alive\r\n"
2745 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322746 };
2747
2748 // Respond with 5 kb of response body.
2749 std::string large_body_string("Unauthorized");
2750 large_body_string.append(5 * 1024, ' ');
2751 large_body_string.append("\r\n");
2752
2753 MockRead data_reads1[] = {
2754 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2755 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2756 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2757 // 5134 = 12 + 5 * 1024 + 2
2758 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062759 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322760
2761 // Lastly, the server responds with the actual content.
2762 MockRead("HTTP/1.1 200 OK\r\n"),
2763 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502764 MockRead("Content-Length: 5\r\n\r\n"),
2765 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322766 };
2767
[email protected]2d0a4f92011-05-05 16:38:462768 // An incorrect reconnect would cause this to be read.
2769 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062770 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462771 };
2772
[email protected]31a2bfe2010-02-09 08:03:392773 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2774 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462775 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2776 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072777 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2778 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322779
[email protected]49639fa2011-12-20 23:22:412780 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322781
bnc691fda62016-08-12 00:43:162782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202783 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322785
2786 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012787 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322788
bnc691fda62016-08-12 00:43:162789 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522790 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042791 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322792
[email protected]49639fa2011-12-20 23:22:412793 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322794
bnc691fda62016-08-12 00:43:162795 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322797
2798 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012799 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322800
bnc691fda62016-08-12 00:43:162801 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522802 ASSERT_TRUE(response);
2803 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502804 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322805}
2806
2807// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312808// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012809TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312810 HttpRequestInfo request;
2811 request.method = "GET";
bncce36dca22015-04-21 22:11:232812 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312813
danakj1fd259a02016-04-16 03:17:092814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272815
[email protected]11203f012009-11-12 23:02:312816 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232817 MockWrite(
2818 "GET / HTTP/1.1\r\n"
2819 "Host: www.example.org\r\n"
2820 "Connection: keep-alive\r\n\r\n"),
2821 // This simulates the seemingly successful write to a closed connection
2822 // if the bug is not fixed.
2823 MockWrite(
2824 "GET / HTTP/1.1\r\n"
2825 "Host: www.example.org\r\n"
2826 "Connection: keep-alive\r\n"
2827 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312828 };
2829
2830 MockRead data_reads1[] = {
2831 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2832 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2833 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2834 MockRead("Content-Length: 14\r\n\r\n"),
2835 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062836 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312837 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062838 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312839 };
2840
bnc691fda62016-08-12 00:43:162841 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312842 // be issuing -- the final header line contains the credentials.
2843 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232844 MockWrite(
2845 "GET / HTTP/1.1\r\n"
2846 "Host: www.example.org\r\n"
2847 "Connection: keep-alive\r\n"
2848 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312849 };
2850
2851 // Lastly, the server responds with the actual content.
2852 MockRead data_reads2[] = {
2853 MockRead("HTTP/1.1 200 OK\r\n"),
2854 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502855 MockRead("Content-Length: 5\r\n\r\n"),
2856 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312857 };
2858
[email protected]31a2bfe2010-02-09 08:03:392859 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2860 data_writes1, arraysize(data_writes1));
2861 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2862 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072863 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2864 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312865
[email protected]49639fa2011-12-20 23:22:412866 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312867
bnc691fda62016-08-12 00:43:162868 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202869 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012870 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312871
2872 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012873 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312874
bnc691fda62016-08-12 00:43:162875 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522876 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042877 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312878
[email protected]49639fa2011-12-20 23:22:412879 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312880
bnc691fda62016-08-12 00:43:162881 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312883
2884 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012885 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312886
bnc691fda62016-08-12 00:43:162887 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522888 ASSERT_TRUE(response);
2889 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502890 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312891}
2892
[email protected]394816e92010-08-03 07:38:592893// Test the request-challenge-retry sequence for basic auth, over a connection
2894// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012895TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012896 HttpRequestInfo request;
2897 request.method = "GET";
bncce36dca22015-04-21 22:11:232898 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012899 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292900 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012901
2902 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032903 session_deps_.proxy_service =
2904 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512905 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012906 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012908
2909 // Since we have proxy, should try to establish tunnel.
2910 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542911 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172912 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542913 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012914 };
2915
mmenkee71e15332015-10-07 16:39:542916 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012917 // connection.
2918 MockRead data_reads1[] = {
2919 // No credentials.
2920 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2921 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542922 };
ttuttle34f63b52015-03-05 04:33:012923
mmenkee71e15332015-10-07 16:39:542924 // Since the first connection couldn't be reused, need to establish another
2925 // once given credentials.
2926 MockWrite data_writes2[] = {
2927 // After calling trans->RestartWithAuth(), this is the request we should
2928 // be issuing -- the final header line contains the credentials.
2929 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172930 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542931 "Proxy-Connection: keep-alive\r\n"
2932 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2933
2934 MockWrite("GET / HTTP/1.1\r\n"
2935 "Host: www.example.org\r\n"
2936 "Connection: keep-alive\r\n\r\n"),
2937 };
2938
2939 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012940 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2941
2942 MockRead("HTTP/1.1 200 OK\r\n"),
2943 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2944 MockRead("Content-Length: 5\r\n\r\n"),
2945 MockRead(SYNCHRONOUS, "hello"),
2946 };
2947
2948 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2949 data_writes1, arraysize(data_writes1));
2950 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542951 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2952 data_writes2, arraysize(data_writes2));
2953 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012954 SSLSocketDataProvider ssl(ASYNC, OK);
2955 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2956
2957 TestCompletionCallback callback1;
2958
bnc87dcefc2017-05-25 12:47:582959 auto trans =
2960 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:012961
2962 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012964
2965 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012966 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462967 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012968 log.GetEntries(&entries);
2969 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002970 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2971 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012972 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002973 entries, pos,
2974 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2975 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012976
2977 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522978 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012979 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522980 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012981 EXPECT_EQ(407, response->headers->response_code());
2982 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2983 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2984
2985 LoadTimingInfo load_timing_info;
2986 // CONNECT requests and responses are handled at the connect job level, so
2987 // the transaction does not yet have a connection.
2988 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2989
2990 TestCompletionCallback callback2;
2991
2992 rv =
2993 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012995
2996 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012997 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:012998
2999 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523000 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013001
3002 EXPECT_TRUE(response->headers->IsKeepAlive());
3003 EXPECT_EQ(200, response->headers->response_code());
3004 EXPECT_EQ(5, response->headers->GetContentLength());
3005 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3006
3007 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523008 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013009
3010 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3011 TestLoadTimingNotReusedWithPac(load_timing_info,
3012 CONNECT_TIMING_HAS_SSL_TIMES);
3013
3014 trans.reset();
3015 session->CloseAllConnections();
3016}
3017
3018// Test the request-challenge-retry sequence for basic auth, over a connection
3019// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013020TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593021 HttpRequestInfo request;
3022 request.method = "GET";
bncce36dca22015-04-21 22:11:233023 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593024 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293025 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593026
[email protected]cb9bf6ca2011-01-28 13:15:273027 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033028 session_deps_.proxy_service =
3029 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513030 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073031 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273033
[email protected]394816e92010-08-03 07:38:593034 // Since we have proxy, should try to establish tunnel.
3035 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543036 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173037 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543038 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113039 };
3040
mmenkee71e15332015-10-07 16:39:543041 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083042 // connection.
3043 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543044 // No credentials.
3045 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3046 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3047 MockRead("Proxy-Connection: close\r\n\r\n"),
3048 };
mmenkee0b5c882015-08-26 20:29:113049
mmenkee71e15332015-10-07 16:39:543050 MockWrite data_writes2[] = {
3051 // After calling trans->RestartWithAuth(), this is the request we should
3052 // be issuing -- the final header line contains the credentials.
3053 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173054 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543055 "Proxy-Connection: keep-alive\r\n"
3056 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083057
mmenkee71e15332015-10-07 16:39:543058 MockWrite("GET / HTTP/1.1\r\n"
3059 "Host: www.example.org\r\n"
3060 "Connection: keep-alive\r\n\r\n"),
3061 };
3062
3063 MockRead data_reads2[] = {
3064 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3065
3066 MockRead("HTTP/1.1 200 OK\r\n"),
3067 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3068 MockRead("Content-Length: 5\r\n\r\n"),
3069 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593070 };
3071
3072 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3073 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073074 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543075 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3076 data_writes2, arraysize(data_writes2));
3077 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063078 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593080
[email protected]49639fa2011-12-20 23:22:413081 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593082
bnc87dcefc2017-05-25 12:47:583083 auto trans =
3084 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503085
[email protected]49639fa2011-12-20 23:22:413086 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593088
3089 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013090 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463091 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403092 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593093 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003094 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3095 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593096 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403097 entries, pos,
mikecirone8b85c432016-09-08 19:11:003098 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3099 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593100
3101 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523102 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013103 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523104 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593105 EXPECT_EQ(407, response->headers->response_code());
3106 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043107 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593108
[email protected]029c83b62013-01-24 05:28:203109 LoadTimingInfo load_timing_info;
3110 // CONNECT requests and responses are handled at the connect job level, so
3111 // the transaction does not yet have a connection.
3112 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3113
[email protected]49639fa2011-12-20 23:22:413114 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593115
[email protected]49639fa2011-12-20 23:22:413116 rv = trans->RestartWithAuth(
3117 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593119
3120 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013121 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593122
3123 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523124 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593125
3126 EXPECT_TRUE(response->headers->IsKeepAlive());
3127 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503128 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593129 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3130
3131 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523132 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503133
[email protected]029c83b62013-01-24 05:28:203134 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3135 TestLoadTimingNotReusedWithPac(load_timing_info,
3136 CONNECT_TIMING_HAS_SSL_TIMES);
3137
[email protected]0b0bf032010-09-21 18:08:503138 trans.reset();
[email protected]102e27c2011-02-23 01:01:313139 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593140}
3141
[email protected]11203f012009-11-12 23:02:313142// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013143// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013144TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233145 // On the second pass, the body read of the auth challenge is synchronous, so
3146 // IsConnectedAndIdle returns false. The socket should still be drained and
3147 // reused. See http://crbug.com/544255.
3148 for (int i = 0; i < 2; ++i) {
3149 HttpRequestInfo request;
3150 request.method = "GET";
3151 request.url = GURL("https://www.example.org/");
3152 // Ensure that proxy authentication is attempted even
3153 // when the no authentication data flag is set.
3154 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013155
mmenked39192ee2015-12-09 00:57:233156 // Configure against proxy server "myproxy:70".
3157 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3158 BoundTestNetLog log;
3159 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093160 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013161
bnc691fda62016-08-12 00:43:163162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013163
mmenked39192ee2015-12-09 00:57:233164 // Since we have proxy, should try to establish tunnel.
3165 MockWrite data_writes1[] = {
3166 MockWrite(ASYNC, 0,
3167 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3168 "Host: www.example.org:443\r\n"
3169 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013170
bnc691fda62016-08-12 00:43:163171 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233172 // be issuing -- the final header line contains the credentials.
3173 MockWrite(ASYNC, 3,
3174 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3175 "Host: www.example.org:443\r\n"
3176 "Proxy-Connection: keep-alive\r\n"
3177 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3178 };
ttuttle34f63b52015-03-05 04:33:013179
mmenked39192ee2015-12-09 00:57:233180 // The proxy responds to the connect with a 407, using a persistent
3181 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3182 MockRead data_reads1[] = {
3183 // No credentials.
3184 MockRead(ASYNC, 1,
3185 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3186 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3187 "Proxy-Connection: keep-alive\r\n"
3188 "Content-Length: 10\r\n\r\n"),
3189 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013190
mmenked39192ee2015-12-09 00:57:233191 // Wrong credentials (wrong password).
3192 MockRead(ASYNC, 4,
3193 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3194 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3195 "Proxy-Connection: keep-alive\r\n"
3196 "Content-Length: 10\r\n\r\n"),
3197 // No response body because the test stops reading here.
3198 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3199 };
ttuttle34f63b52015-03-05 04:33:013200
mmenked39192ee2015-12-09 00:57:233201 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3202 arraysize(data_writes1));
3203 data1.set_busy_before_sync_reads(true);
3204 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013205
mmenked39192ee2015-12-09 00:57:233206 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013207
bnc691fda62016-08-12 00:43:163208 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013209 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013210
mmenked39192ee2015-12-09 00:57:233211 TestNetLogEntry::List entries;
3212 log.GetEntries(&entries);
3213 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003214 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3215 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233216 ExpectLogContainsSomewhere(
3217 entries, pos,
mikecirone8b85c432016-09-08 19:11:003218 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3219 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013220
bnc691fda62016-08-12 00:43:163221 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233222 ASSERT_TRUE(response);
3223 ASSERT_TRUE(response->headers);
3224 EXPECT_TRUE(response->headers->IsKeepAlive());
3225 EXPECT_EQ(407, response->headers->response_code());
3226 EXPECT_EQ(10, response->headers->GetContentLength());
3227 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3228 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013229
mmenked39192ee2015-12-09 00:57:233230 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013231
mmenked39192ee2015-12-09 00:57:233232 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163233 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3234 callback2.callback());
robpercival214763f2016-07-01 23:27:013235 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013236
bnc691fda62016-08-12 00:43:163237 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233238 ASSERT_TRUE(response);
3239 ASSERT_TRUE(response->headers);
3240 EXPECT_TRUE(response->headers->IsKeepAlive());
3241 EXPECT_EQ(407, response->headers->response_code());
3242 EXPECT_EQ(10, response->headers->GetContentLength());
3243 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3244 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013245
mmenked39192ee2015-12-09 00:57:233246 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3247 // out of scope.
3248 session->CloseAllConnections();
3249 }
ttuttle34f63b52015-03-05 04:33:013250}
3251
3252// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3253// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013254TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233255 // On the second pass, the body read of the auth challenge is synchronous, so
3256 // IsConnectedAndIdle returns false. The socket should still be drained and
3257 // reused. See http://crbug.com/544255.
3258 for (int i = 0; i < 2; ++i) {
3259 HttpRequestInfo request;
3260 request.method = "GET";
3261 request.url = GURL("https://www.example.org/");
3262 // Ensure that proxy authentication is attempted even
3263 // when the no authentication data flag is set.
3264 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3265
3266 // Configure against proxy server "myproxy:70".
3267 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3268 BoundTestNetLog log;
3269 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093270 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233271
bnc691fda62016-08-12 00:43:163272 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233273
3274 // Since we have proxy, should try to establish tunnel.
3275 MockWrite data_writes1[] = {
3276 MockWrite(ASYNC, 0,
3277 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3278 "Host: www.example.org:443\r\n"
3279 "Proxy-Connection: keep-alive\r\n\r\n"),
3280
bnc691fda62016-08-12 00:43:163281 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233282 // be issuing -- the final header line contains the credentials.
3283 MockWrite(ASYNC, 3,
3284 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3285 "Host: www.example.org:443\r\n"
3286 "Proxy-Connection: keep-alive\r\n"
3287 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3288 };
3289
3290 // The proxy responds to the connect with a 407, using a persistent
3291 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3292 MockRead data_reads1[] = {
3293 // No credentials.
3294 MockRead(ASYNC, 1,
3295 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3296 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3297 "Content-Length: 10\r\n\r\n"),
3298 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3299
3300 // Wrong credentials (wrong password).
3301 MockRead(ASYNC, 4,
3302 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3303 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3304 "Content-Length: 10\r\n\r\n"),
3305 // No response body because the test stops reading here.
3306 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3307 };
3308
3309 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3310 arraysize(data_writes1));
3311 data1.set_busy_before_sync_reads(true);
3312 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3313
3314 TestCompletionCallback callback1;
3315
bnc691fda62016-08-12 00:43:163316 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013317 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233318
3319 TestNetLogEntry::List entries;
3320 log.GetEntries(&entries);
3321 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003322 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3323 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233324 ExpectLogContainsSomewhere(
3325 entries, pos,
mikecirone8b85c432016-09-08 19:11:003326 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3327 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233328
bnc691fda62016-08-12 00:43:163329 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233330 ASSERT_TRUE(response);
3331 ASSERT_TRUE(response->headers);
3332 EXPECT_TRUE(response->headers->IsKeepAlive());
3333 EXPECT_EQ(407, response->headers->response_code());
3334 EXPECT_EQ(10, response->headers->GetContentLength());
3335 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3336 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3337
3338 TestCompletionCallback callback2;
3339
3340 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163341 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3342 callback2.callback());
robpercival214763f2016-07-01 23:27:013343 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233344
bnc691fda62016-08-12 00:43:163345 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233346 ASSERT_TRUE(response);
3347 ASSERT_TRUE(response->headers);
3348 EXPECT_TRUE(response->headers->IsKeepAlive());
3349 EXPECT_EQ(407, response->headers->response_code());
3350 EXPECT_EQ(10, response->headers->GetContentLength());
3351 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3352 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3353
3354 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3355 // out of scope.
3356 session->CloseAllConnections();
3357 }
3358}
3359
3360// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3361// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3362// the case the server sends extra data on the original socket, so it can't be
3363// reused.
bncd16676a2016-07-20 16:23:013364TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273365 HttpRequestInfo request;
3366 request.method = "GET";
bncce36dca22015-04-21 22:11:233367 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273368 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293369 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273370
[email protected]2d2697f92009-02-18 21:00:323371 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233372 session_deps_.proxy_service =
3373 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513374 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073375 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323377
[email protected]2d2697f92009-02-18 21:00:323378 // Since we have proxy, should try to establish tunnel.
3379 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233380 MockWrite(ASYNC, 0,
3381 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173382 "Host: www.example.org:443\r\n"
3383 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233384 };
[email protected]2d2697f92009-02-18 21:00:323385
mmenked39192ee2015-12-09 00:57:233386 // The proxy responds to the connect with a 407, using a persistent, but sends
3387 // extra data, so the socket cannot be reused.
3388 MockRead data_reads1[] = {
3389 // No credentials.
3390 MockRead(ASYNC, 1,
3391 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3392 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3393 "Content-Length: 10\r\n\r\n"),
3394 MockRead(SYNCHRONOUS, 2, "0123456789"),
3395 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3396 };
3397
3398 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233399 // After calling trans->RestartWithAuth(), this is the request we should
3400 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233401 MockWrite(ASYNC, 0,
3402 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173403 "Host: www.example.org:443\r\n"
3404 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233405 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3406
3407 MockWrite(ASYNC, 2,
3408 "GET / HTTP/1.1\r\n"
3409 "Host: www.example.org\r\n"
3410 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323411 };
3412
mmenked39192ee2015-12-09 00:57:233413 MockRead data_reads2[] = {
3414 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323415
mmenked39192ee2015-12-09 00:57:233416 MockRead(ASYNC, 3,
3417 "HTTP/1.1 200 OK\r\n"
3418 "Content-Type: text/html; charset=iso-8859-1\r\n"
3419 "Content-Length: 5\r\n\r\n"),
3420 // No response body because the test stops reading here.
3421 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323422 };
3423
mmenked39192ee2015-12-09 00:57:233424 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3425 arraysize(data_writes1));
3426 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233428 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3429 arraysize(data_writes2));
3430 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3431 SSLSocketDataProvider ssl(ASYNC, OK);
3432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323433
[email protected]49639fa2011-12-20 23:22:413434 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323435
bnc87dcefc2017-05-25 12:47:583436 auto trans =
3437 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323438
mmenked39192ee2015-12-09 00:57:233439 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013440 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233441
mmenke43758e62015-05-04 21:09:463442 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403443 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393444 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003445 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3446 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393447 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403448 entries, pos,
mikecirone8b85c432016-09-08 19:11:003449 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3450 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323451
[email protected]1c773ea12009-04-28 19:58:423452 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243453 ASSERT_TRUE(response);
3454 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323455 EXPECT_TRUE(response->headers->IsKeepAlive());
3456 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423457 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043458 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323459
mmenked39192ee2015-12-09 00:57:233460 LoadTimingInfo load_timing_info;
3461 // CONNECT requests and responses are handled at the connect job level, so
3462 // the transaction does not yet have a connection.
3463 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3464
[email protected]49639fa2011-12-20 23:22:413465 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323466
mmenked39192ee2015-12-09 00:57:233467 rv =
3468 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013469 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323470
[email protected]2d2697f92009-02-18 21:00:323471 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233472 EXPECT_EQ(200, response->headers->response_code());
3473 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423474 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133475
mmenked39192ee2015-12-09 00:57:233476 // The password prompt info should not be set.
3477 EXPECT_FALSE(response->auth_challenge);
3478
3479 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3480 TestLoadTimingNotReusedWithPac(load_timing_info,
3481 CONNECT_TIMING_HAS_SSL_TIMES);
3482
3483 trans.reset();
[email protected]102e27c2011-02-23 01:01:313484 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323485}
3486
mmenkee71e15332015-10-07 16:39:543487// Test the case a proxy closes a socket while the challenge body is being
3488// drained.
bncd16676a2016-07-20 16:23:013489TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543490 HttpRequestInfo request;
3491 request.method = "GET";
3492 request.url = GURL("https://www.example.org/");
3493 // Ensure that proxy authentication is attempted even
3494 // when the no authentication data flag is set.
3495 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3496
3497 // Configure against proxy server "myproxy:70".
3498 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093499 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543500
bnc691fda62016-08-12 00:43:163501 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543502
3503 // Since we have proxy, should try to establish tunnel.
3504 MockWrite data_writes1[] = {
3505 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173506 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543507 "Proxy-Connection: keep-alive\r\n\r\n"),
3508 };
3509
3510 // The proxy responds to the connect with a 407, using a persistent
3511 // connection.
3512 MockRead data_reads1[] = {
3513 // No credentials.
3514 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3515 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3516 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3517 // Server hands up in the middle of the body.
3518 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3519 };
3520
3521 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163522 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543523 // be issuing -- the final header line contains the credentials.
3524 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173525 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543526 "Proxy-Connection: keep-alive\r\n"
3527 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3528
3529 MockWrite("GET / HTTP/1.1\r\n"
3530 "Host: www.example.org\r\n"
3531 "Connection: keep-alive\r\n\r\n"),
3532 };
3533
3534 MockRead data_reads2[] = {
3535 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3536
3537 MockRead("HTTP/1.1 200 OK\r\n"),
3538 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3539 MockRead("Content-Length: 5\r\n\r\n"),
3540 MockRead(SYNCHRONOUS, "hello"),
3541 };
3542
3543 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3544 data_writes1, arraysize(data_writes1));
3545 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3546 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3547 data_writes2, arraysize(data_writes2));
3548 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3549 SSLSocketDataProvider ssl(ASYNC, OK);
3550 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3551
3552 TestCompletionCallback callback;
3553
tfarina42834112016-09-22 13:38:203554 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013555 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543556
bnc691fda62016-08-12 00:43:163557 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543558 ASSERT_TRUE(response);
3559 ASSERT_TRUE(response->headers);
3560 EXPECT_TRUE(response->headers->IsKeepAlive());
3561 EXPECT_EQ(407, response->headers->response_code());
3562 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3563
bnc691fda62016-08-12 00:43:163564 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013565 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543566
bnc691fda62016-08-12 00:43:163567 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543568 ASSERT_TRUE(response);
3569 ASSERT_TRUE(response->headers);
3570 EXPECT_TRUE(response->headers->IsKeepAlive());
3571 EXPECT_EQ(200, response->headers->response_code());
3572 std::string body;
bnc691fda62016-08-12 00:43:163573 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543574 EXPECT_EQ("hello", body);
3575}
3576
[email protected]a8e9b162009-03-12 00:06:443577// Test that we don't read the response body when we fail to establish a tunnel,
3578// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013579TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273580 HttpRequestInfo request;
3581 request.method = "GET";
bncce36dca22015-04-21 22:11:233582 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273583
[email protected]a8e9b162009-03-12 00:06:443584 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033585 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443586
danakj1fd259a02016-04-16 03:17:093587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443588
bnc691fda62016-08-12 00:43:163589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443590
[email protected]a8e9b162009-03-12 00:06:443591 // Since we have proxy, should try to establish tunnel.
3592 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173593 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3594 "Host: www.example.org:443\r\n"
3595 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443596 };
3597
3598 // The proxy responds to the connect with a 407.
3599 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243600 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3601 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3602 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233603 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243604 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443605 };
3606
[email protected]31a2bfe2010-02-09 08:03:393607 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3608 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073609 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443610
[email protected]49639fa2011-12-20 23:22:413611 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443612
tfarina42834112016-09-22 13:38:203613 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013614 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443615
3616 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013617 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443618
bnc691fda62016-08-12 00:43:163619 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243620 ASSERT_TRUE(response);
3621 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443622 EXPECT_TRUE(response->headers->IsKeepAlive());
3623 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423624 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443625
3626 std::string response_data;
bnc691fda62016-08-12 00:43:163627 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013628 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183629
3630 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313631 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443632}
3633
ttuttle7933c112015-01-06 00:55:243634// Test that we don't pass extraneous headers from the proxy's response to the
3635// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013636TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243637 HttpRequestInfo request;
3638 request.method = "GET";
bncce36dca22015-04-21 22:11:233639 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243640
3641 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033642 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243643
danakj1fd259a02016-04-16 03:17:093644 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243645
bnc691fda62016-08-12 00:43:163646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243647
3648 // Since we have proxy, should try to establish tunnel.
3649 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173650 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3651 "Host: www.example.org:443\r\n"
3652 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243653 };
3654
3655 // The proxy responds to the connect with a 407.
3656 MockRead data_reads[] = {
3657 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3658 MockRead("X-Foo: bar\r\n"),
3659 MockRead("Set-Cookie: foo=bar\r\n"),
3660 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3661 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233662 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243663 };
3664
3665 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3666 arraysize(data_writes));
3667 session_deps_.socket_factory->AddSocketDataProvider(&data);
3668
3669 TestCompletionCallback callback;
3670
tfarina42834112016-09-22 13:38:203671 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243673
3674 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013675 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243676
bnc691fda62016-08-12 00:43:163677 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243678 ASSERT_TRUE(response);
3679 ASSERT_TRUE(response->headers);
3680 EXPECT_TRUE(response->headers->IsKeepAlive());
3681 EXPECT_EQ(407, response->headers->response_code());
3682 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3683 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3684 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3685
3686 std::string response_data;
bnc691fda62016-08-12 00:43:163687 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013688 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243689
3690 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3691 session->CloseAllConnections();
3692}
3693
[email protected]8fdbcd22010-05-05 02:54:523694// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3695// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013696TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523697 HttpRequestInfo request;
3698 request.method = "GET";
bncce36dca22015-04-21 22:11:233699 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523700
[email protected]cb9bf6ca2011-01-28 13:15:273701 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093702 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273704
[email protected]8fdbcd22010-05-05 02:54:523705 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233706 MockWrite(
3707 "GET / HTTP/1.1\r\n"
3708 "Host: www.example.org\r\n"
3709 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523710 };
3711
3712 MockRead data_reads1[] = {
3713 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3714 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3715 // Large content-length -- won't matter, as connection will be reset.
3716 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063717 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523718 };
3719
3720 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3721 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073722 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523723
[email protected]49639fa2011-12-20 23:22:413724 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523725
tfarina42834112016-09-22 13:38:203726 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523728
3729 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013730 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523731}
3732
[email protected]7a67a8152010-11-05 18:31:103733// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3734// through a non-authenticating proxy. The request should fail with
3735// ERR_UNEXPECTED_PROXY_AUTH.
3736// Note that it is impossible to detect if an HTTP server returns a 407 through
3737// a non-authenticating proxy - there is nothing to indicate whether the
3738// response came from the proxy or the server, so it is treated as if the proxy
3739// issued the challenge.
bncd16676a2016-07-20 16:23:013740TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273741 HttpRequestInfo request;
3742 request.method = "GET";
bncce36dca22015-04-21 22:11:233743 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273744
rdsmith82957ad2015-09-16 19:42:033745 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513746 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073747 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103749
[email protected]7a67a8152010-11-05 18:31:103750 // Since we have proxy, should try to establish tunnel.
3751 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173752 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3753 "Host: www.example.org:443\r\n"
3754 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103755
rsleevidb16bb02015-11-12 23:47:173756 MockWrite("GET / HTTP/1.1\r\n"
3757 "Host: www.example.org\r\n"
3758 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103759 };
3760
3761 MockRead data_reads1[] = {
3762 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3763
3764 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3765 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3766 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063767 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103768 };
3769
3770 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3771 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073772 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063773 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073774 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103775
[email protected]49639fa2011-12-20 23:22:413776 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103777
bnc691fda62016-08-12 00:43:163778 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103779
bnc691fda62016-08-12 00:43:163780 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013781 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103782
3783 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013784 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463785 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403786 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103787 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003788 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3789 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103790 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403791 entries, pos,
mikecirone8b85c432016-09-08 19:11:003792 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3793 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103794}
[email protected]2df19bb2010-08-25 20:13:463795
mmenke2a1781d2015-10-07 19:25:333796// Test a proxy auth scheme that allows default credentials and a proxy server
3797// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013798TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333799 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3800 HttpRequestInfo request;
3801 request.method = "GET";
3802 request.url = GURL("https://www.example.org/");
3803
3804 // Configure against proxy server "myproxy:70".
3805 session_deps_.proxy_service =
3806 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3807
bnc87dcefc2017-05-25 12:47:583808 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333809 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583810 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333811 mock_handler->set_allows_default_credentials(true);
3812 auth_handler_factory->AddMockHandler(mock_handler.release(),
3813 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483814 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333815
3816 // Add NetLog just so can verify load timing information gets a NetLog ID.
3817 NetLog net_log;
3818 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093819 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333820
3821 // Since we have proxy, should try to establish tunnel.
3822 MockWrite data_writes1[] = {
3823 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173824 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333825 "Proxy-Connection: keep-alive\r\n\r\n"),
3826 };
3827
3828 // The proxy responds to the connect with a 407, using a non-persistent
3829 // connection.
3830 MockRead data_reads1[] = {
3831 // No credentials.
3832 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3833 MockRead("Proxy-Authenticate: Mock\r\n"),
3834 MockRead("Proxy-Connection: close\r\n\r\n"),
3835 };
3836
3837 // Since the first connection couldn't be reused, need to establish another
3838 // once given credentials.
3839 MockWrite data_writes2[] = {
3840 // After calling trans->RestartWithAuth(), this is the request we should
3841 // be issuing -- the final header line contains the credentials.
3842 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173843 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333844 "Proxy-Connection: keep-alive\r\n"
3845 "Proxy-Authorization: auth_token\r\n\r\n"),
3846
3847 MockWrite("GET / HTTP/1.1\r\n"
3848 "Host: www.example.org\r\n"
3849 "Connection: keep-alive\r\n\r\n"),
3850 };
3851
3852 MockRead data_reads2[] = {
3853 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3854
3855 MockRead("HTTP/1.1 200 OK\r\n"),
3856 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3857 MockRead("Content-Length: 5\r\n\r\n"),
3858 MockRead(SYNCHRONOUS, "hello"),
3859 };
3860
3861 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3862 data_writes1, arraysize(data_writes1));
3863 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3864 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3865 data_writes2, arraysize(data_writes2));
3866 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3867 SSLSocketDataProvider ssl(ASYNC, OK);
3868 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3869
bnc87dcefc2017-05-25 12:47:583870 auto trans =
3871 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333872
3873 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203874 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013875 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333876
3877 const HttpResponseInfo* response = trans->GetResponseInfo();
3878 ASSERT_TRUE(response);
3879 ASSERT_TRUE(response->headers);
3880 EXPECT_FALSE(response->headers->IsKeepAlive());
3881 EXPECT_EQ(407, response->headers->response_code());
3882 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3883 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523884 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333885
3886 LoadTimingInfo load_timing_info;
3887 // CONNECT requests and responses are handled at the connect job level, so
3888 // the transaction does not yet have a connection.
3889 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3890
3891 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013892 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333893 response = trans->GetResponseInfo();
3894 ASSERT_TRUE(response);
3895 ASSERT_TRUE(response->headers);
3896 EXPECT_TRUE(response->headers->IsKeepAlive());
3897 EXPECT_EQ(200, response->headers->response_code());
3898 EXPECT_EQ(5, response->headers->GetContentLength());
3899 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3900
3901 // The password prompt info should not be set.
3902 EXPECT_FALSE(response->auth_challenge);
3903
3904 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3905 TestLoadTimingNotReusedWithPac(load_timing_info,
3906 CONNECT_TIMING_HAS_SSL_TIMES);
3907
3908 trans.reset();
3909 session->CloseAllConnections();
3910}
3911
3912// Test a proxy auth scheme that allows default credentials and a proxy server
3913// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013914TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333915 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3916 HttpRequestInfo request;
3917 request.method = "GET";
3918 request.url = GURL("https://www.example.org/");
3919
3920 // Configure against proxy server "myproxy:70".
3921 session_deps_.proxy_service =
3922 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3923
bnc87dcefc2017-05-25 12:47:583924 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333925 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:583926 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333927 mock_handler->set_allows_default_credentials(true);
3928 auth_handler_factory->AddMockHandler(mock_handler.release(),
3929 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483930 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333931
3932 // Add NetLog just so can verify load timing information gets a NetLog ID.
3933 NetLog net_log;
3934 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093935 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333936
3937 // Should try to establish tunnel.
3938 MockWrite data_writes1[] = {
3939 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173940 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333941 "Proxy-Connection: keep-alive\r\n\r\n"),
3942
3943 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173944 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333945 "Proxy-Connection: keep-alive\r\n"
3946 "Proxy-Authorization: auth_token\r\n\r\n"),
3947 };
3948
3949 // The proxy responds to the connect with a 407, using a non-persistent
3950 // connection.
3951 MockRead data_reads1[] = {
3952 // No credentials.
3953 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3954 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3955 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3956 };
3957
3958 // Since the first connection was closed, need to establish another once given
3959 // credentials.
3960 MockWrite data_writes2[] = {
3961 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173962 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333963 "Proxy-Connection: keep-alive\r\n"
3964 "Proxy-Authorization: auth_token\r\n\r\n"),
3965
3966 MockWrite("GET / HTTP/1.1\r\n"
3967 "Host: www.example.org\r\n"
3968 "Connection: keep-alive\r\n\r\n"),
3969 };
3970
3971 MockRead data_reads2[] = {
3972 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3973
3974 MockRead("HTTP/1.1 200 OK\r\n"),
3975 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3976 MockRead("Content-Length: 5\r\n\r\n"),
3977 MockRead(SYNCHRONOUS, "hello"),
3978 };
3979
3980 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3981 data_writes1, arraysize(data_writes1));
3982 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3983 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3984 data_writes2, arraysize(data_writes2));
3985 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3986 SSLSocketDataProvider ssl(ASYNC, OK);
3987 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3988
bnc87dcefc2017-05-25 12:47:583989 auto trans =
3990 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333991
3992 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203993 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013994 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333995
3996 const HttpResponseInfo* response = trans->GetResponseInfo();
3997 ASSERT_TRUE(response);
3998 ASSERT_TRUE(response->headers);
3999 EXPECT_TRUE(response->headers->IsKeepAlive());
4000 EXPECT_EQ(407, response->headers->response_code());
4001 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4002 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4003 EXPECT_FALSE(response->auth_challenge);
4004
4005 LoadTimingInfo load_timing_info;
4006 // CONNECT requests and responses are handled at the connect job level, so
4007 // the transaction does not yet have a connection.
4008 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4009
4010 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014011 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334012
4013 response = trans->GetResponseInfo();
4014 ASSERT_TRUE(response);
4015 ASSERT_TRUE(response->headers);
4016 EXPECT_TRUE(response->headers->IsKeepAlive());
4017 EXPECT_EQ(200, response->headers->response_code());
4018 EXPECT_EQ(5, response->headers->GetContentLength());
4019 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4020
4021 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524022 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334023
4024 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4025 TestLoadTimingNotReusedWithPac(load_timing_info,
4026 CONNECT_TIMING_HAS_SSL_TIMES);
4027
4028 trans.reset();
4029 session->CloseAllConnections();
4030}
4031
4032// Test a proxy auth scheme that allows default credentials and a proxy server
4033// that hangs up when credentials are initially sent, and hangs up again when
4034// they are retried.
bncd16676a2016-07-20 16:23:014035TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334036 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4037 HttpRequestInfo request;
4038 request.method = "GET";
4039 request.url = GURL("https://www.example.org/");
4040
4041 // Configure against proxy server "myproxy:70".
4042 session_deps_.proxy_service =
4043 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4044
bnc87dcefc2017-05-25 12:47:584045 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334046 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584047 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334048 mock_handler->set_allows_default_credentials(true);
4049 auth_handler_factory->AddMockHandler(mock_handler.release(),
4050 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484051 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334052
4053 // Add NetLog just so can verify load timing information gets a NetLog ID.
4054 NetLog net_log;
4055 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094056 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334057
4058 // Should try to establish tunnel.
4059 MockWrite data_writes1[] = {
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\r\n"),
4063
4064 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174065 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334066 "Proxy-Connection: keep-alive\r\n"
4067 "Proxy-Authorization: auth_token\r\n\r\n"),
4068 };
4069
4070 // The proxy responds to the connect with a 407, and then hangs up after the
4071 // second request is sent.
4072 MockRead data_reads1[] = {
4073 // No credentials.
4074 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4075 MockRead("Content-Length: 0\r\n"),
4076 MockRead("Proxy-Connection: keep-alive\r\n"),
4077 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4078 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4079 };
4080
4081 // HttpNetworkTransaction sees a reused connection that was closed with
4082 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4083 // request.
4084 MockWrite data_writes2[] = {
4085 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174086 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334087 "Proxy-Connection: keep-alive\r\n\r\n"),
4088 };
4089
4090 // The proxy, having had more than enough of us, just hangs up.
4091 MockRead data_reads2[] = {
4092 // No credentials.
4093 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4094 };
4095
4096 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4097 data_writes1, arraysize(data_writes1));
4098 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4099 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4100 data_writes2, arraysize(data_writes2));
4101 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4102
bnc87dcefc2017-05-25 12:47:584103 auto trans =
4104 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334105
4106 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204107 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014108 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334109
4110 const HttpResponseInfo* response = trans->GetResponseInfo();
4111 ASSERT_TRUE(response);
4112 ASSERT_TRUE(response->headers);
4113 EXPECT_TRUE(response->headers->IsKeepAlive());
4114 EXPECT_EQ(407, response->headers->response_code());
4115 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4116 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4117 EXPECT_FALSE(response->auth_challenge);
4118
4119 LoadTimingInfo load_timing_info;
4120 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4121
4122 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014123 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334124
4125 trans.reset();
4126 session->CloseAllConnections();
4127}
4128
4129// Test a proxy auth scheme that allows default credentials and a proxy server
4130// that hangs up when credentials are initially sent, and sends a challenge
4131// again they are retried.
bncd16676a2016-07-20 16:23:014132TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334133 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4134 HttpRequestInfo request;
4135 request.method = "GET";
4136 request.url = GURL("https://www.example.org/");
4137
4138 // Configure against proxy server "myproxy:70".
4139 session_deps_.proxy_service =
4140 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4141
bnc87dcefc2017-05-25 12:47:584142 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334143 auth_handler_factory->set_do_init_from_challenge(true);
bnc87dcefc2017-05-25 12:47:584144 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334145 mock_handler->set_allows_default_credentials(true);
4146 auth_handler_factory->AddMockHandler(mock_handler.release(),
4147 HttpAuth::AUTH_PROXY);
4148 // Add another handler for the second challenge. It supports default
4149 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584150 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334151 mock_handler->set_allows_default_credentials(true);
4152 auth_handler_factory->AddMockHandler(mock_handler.release(),
4153 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484154 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334155
4156 // Add NetLog just so can verify load timing information gets a NetLog ID.
4157 NetLog net_log;
4158 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094159 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334160
4161 // Should try to establish tunnel.
4162 MockWrite data_writes1[] = {
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\r\n"),
4166 };
4167
4168 // The proxy responds to the connect with a 407, using a non-persistent
4169 // connection.
4170 MockRead data_reads1[] = {
4171 // No credentials.
4172 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4173 MockRead("Proxy-Authenticate: Mock\r\n"),
4174 MockRead("Proxy-Connection: close\r\n\r\n"),
4175 };
4176
4177 // Since the first connection was closed, need to establish another once given
4178 // credentials.
4179 MockWrite data_writes2[] = {
4180 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174181 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334182 "Proxy-Connection: keep-alive\r\n"
4183 "Proxy-Authorization: auth_token\r\n\r\n"),
4184 };
4185
4186 MockRead data_reads2[] = {
4187 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4188 MockRead("Proxy-Authenticate: Mock\r\n"),
4189 MockRead("Proxy-Connection: close\r\n\r\n"),
4190 };
4191
4192 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4193 data_writes1, arraysize(data_writes1));
4194 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4195 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4196 data_writes2, arraysize(data_writes2));
4197 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4198 SSLSocketDataProvider ssl(ASYNC, OK);
4199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4200
bnc87dcefc2017-05-25 12:47:584201 auto trans =
4202 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334203
4204 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204205 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014206 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334207
4208 const HttpResponseInfo* response = trans->GetResponseInfo();
4209 ASSERT_TRUE(response);
4210 ASSERT_TRUE(response->headers);
4211 EXPECT_EQ(407, response->headers->response_code());
4212 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4213 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4214 EXPECT_FALSE(response->auth_challenge);
4215
4216 LoadTimingInfo load_timing_info;
4217 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4218
4219 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014220 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334221 response = trans->GetResponseInfo();
4222 ASSERT_TRUE(response);
4223 ASSERT_TRUE(response->headers);
4224 EXPECT_EQ(407, response->headers->response_code());
4225 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4226 EXPECT_TRUE(response->auth_challenge);
4227
4228 trans.reset();
4229 session->CloseAllConnections();
4230}
4231
asankae2257db2016-10-11 22:03:164232// A more nuanced test than GenerateAuthToken test which asserts that
4233// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4234// unnecessarily invalidated, and that if the server co-operates, the
4235// authentication handshake can continue with the same scheme but with a
4236// different identity.
4237TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4238 HttpRequestInfo request;
4239 request.method = "GET";
4240 request.url = GURL("http://www.example.org/");
4241
bnc87dcefc2017-05-25 12:47:584242 auto auth_handler_factory = base::MakeUnique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164243 auth_handler_factory->set_do_init_from_challenge(true);
4244
4245 // First handler. Uses default credentials, but barfs at generate auth token.
bnc87dcefc2017-05-25 12:47:584246 auto mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164247 mock_handler->set_allows_default_credentials(true);
4248 mock_handler->set_allows_explicit_credentials(true);
4249 mock_handler->set_connection_based(true);
4250 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4251 auth_handler_factory->AddMockHandler(mock_handler.release(),
4252 HttpAuth::AUTH_SERVER);
4253
4254 // Add another handler for the second challenge. It supports default
4255 // credentials, but they shouldn't be used, since they were already tried.
bnc87dcefc2017-05-25 12:47:584256 mock_handler = base::MakeUnique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164257 mock_handler->set_allows_default_credentials(true);
4258 mock_handler->set_allows_explicit_credentials(true);
4259 mock_handler->set_connection_based(true);
4260 auth_handler_factory->AddMockHandler(mock_handler.release(),
4261 HttpAuth::AUTH_SERVER);
4262 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4263
4264 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4265
4266 MockWrite data_writes1[] = {
4267 MockWrite("GET / HTTP/1.1\r\n"
4268 "Host: www.example.org\r\n"
4269 "Connection: keep-alive\r\n\r\n"),
4270 };
4271
4272 MockRead data_reads1[] = {
4273 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4274 "WWW-Authenticate: Mock\r\n"
4275 "Connection: keep-alive\r\n\r\n"),
4276 };
4277
4278 // Identical to data_writes1[]. The AuthHandler encounters a
4279 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4280 // transaction procceds without an authorization header.
4281 MockWrite data_writes2[] = {
4282 MockWrite("GET / HTTP/1.1\r\n"
4283 "Host: www.example.org\r\n"
4284 "Connection: keep-alive\r\n\r\n"),
4285 };
4286
4287 MockRead data_reads2[] = {
4288 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4289 "WWW-Authenticate: Mock\r\n"
4290 "Connection: keep-alive\r\n\r\n"),
4291 };
4292
4293 MockWrite data_writes3[] = {
4294 MockWrite("GET / HTTP/1.1\r\n"
4295 "Host: www.example.org\r\n"
4296 "Connection: keep-alive\r\n"
4297 "Authorization: auth_token\r\n\r\n"),
4298 };
4299
4300 MockRead data_reads3[] = {
4301 MockRead("HTTP/1.1 200 OK\r\n"
4302 "Content-Length: 5\r\n"
4303 "Content-Type: text/plain\r\n"
4304 "Connection: keep-alive\r\n\r\n"
4305 "Hello"),
4306 };
4307
4308 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4309 data_writes1, arraysize(data_writes1));
4310 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4311
4312 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4313 data_writes2, arraysize(data_writes2));
4314 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4315
4316 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4317 data_writes3, arraysize(data_writes3));
4318 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4319
bnc87dcefc2017-05-25 12:47:584320 auto trans =
4321 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164322
4323 TestCompletionCallback callback;
4324 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4325 EXPECT_THAT(callback.GetResult(rv), IsOk());
4326
4327 const HttpResponseInfo* response = trans->GetResponseInfo();
4328 ASSERT_TRUE(response);
4329 ASSERT_TRUE(response->headers);
4330 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4331
4332 // The following three tests assert that an authentication challenge was
4333 // received and that the stack is ready to respond to the challenge using
4334 // ambient credentials.
4335 EXPECT_EQ(401, response->headers->response_code());
4336 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4337 EXPECT_FALSE(response->auth_challenge);
4338
4339 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4340 EXPECT_THAT(callback.GetResult(rv), IsOk());
4341 response = trans->GetResponseInfo();
4342 ASSERT_TRUE(response);
4343 ASSERT_TRUE(response->headers);
4344
4345 // The following three tests assert that an authentication challenge was
4346 // received and that the stack needs explicit credentials before it is ready
4347 // to respond to the challenge.
4348 EXPECT_EQ(401, response->headers->response_code());
4349 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4350 EXPECT_TRUE(response->auth_challenge);
4351
4352 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4353 EXPECT_THAT(callback.GetResult(rv), IsOk());
4354 response = trans->GetResponseInfo();
4355 ASSERT_TRUE(response);
4356 ASSERT_TRUE(response->headers);
4357 EXPECT_EQ(200, response->headers->response_code());
4358
4359 trans.reset();
4360 session->CloseAllConnections();
4361}
4362
[email protected]029c83b62013-01-24 05:28:204363// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014364TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204365 HttpRequestInfo request1;
4366 request1.method = "GET";
bncce36dca22015-04-21 22:11:234367 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204368
4369 HttpRequestInfo request2;
4370 request2.method = "GET";
bncce36dca22015-04-21 22:11:234371 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204372
4373 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134374 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514375 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074376 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204378
4379 // Since we have proxy, should try to establish tunnel.
4380 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174381 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4382 "Host: www.example.org:443\r\n"
4383 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204384
rsleevidb16bb02015-11-12 23:47:174385 MockWrite("GET /1 HTTP/1.1\r\n"
4386 "Host: www.example.org\r\n"
4387 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204388
rsleevidb16bb02015-11-12 23:47:174389 MockWrite("GET /2 HTTP/1.1\r\n"
4390 "Host: www.example.org\r\n"
4391 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204392 };
4393
4394 // The proxy responds to the connect with a 407, using a persistent
4395 // connection.
4396 MockRead data_reads1[] = {
4397 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4398
4399 MockRead("HTTP/1.1 200 OK\r\n"),
4400 MockRead("Content-Length: 1\r\n\r\n"),
4401 MockRead(SYNCHRONOUS, "1"),
4402
4403 MockRead("HTTP/1.1 200 OK\r\n"),
4404 MockRead("Content-Length: 2\r\n\r\n"),
4405 MockRead(SYNCHRONOUS, "22"),
4406 };
4407
4408 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4409 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074410 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204411 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204413
4414 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584415 auto trans1 =
4416 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204417
4418 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204420
4421 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014422 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204423
4424 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524425 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474426 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524427 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204428 EXPECT_EQ(1, response1->headers->GetContentLength());
4429
4430 LoadTimingInfo load_timing_info1;
4431 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4432 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4433
4434 trans1.reset();
4435
4436 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584437 auto trans2 =
4438 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204439
4440 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204442
4443 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014444 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204445
4446 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524447 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474448 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524449 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204450 EXPECT_EQ(2, response2->headers->GetContentLength());
4451
4452 LoadTimingInfo load_timing_info2;
4453 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4454 TestLoadTimingReused(load_timing_info2);
4455
4456 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4457
4458 trans2.reset();
4459 session->CloseAllConnections();
4460}
4461
4462// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014463TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[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".
rdsmith82957ad2015-09-16 19:42:034473 session_deps_.proxy_service =
4474 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514475 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074476 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094477 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204478
4479 // Since we have proxy, should try to establish tunnel.
4480 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174481 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4482 "Host: www.example.org:443\r\n"
4483 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204484
rsleevidb16bb02015-11-12 23:47:174485 MockWrite("GET /1 HTTP/1.1\r\n"
4486 "Host: www.example.org\r\n"
4487 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204488
rsleevidb16bb02015-11-12 23:47:174489 MockWrite("GET /2 HTTP/1.1\r\n"
4490 "Host: www.example.org\r\n"
4491 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204492 };
4493
4494 // The proxy responds to the connect with a 407, using a persistent
4495 // connection.
4496 MockRead data_reads1[] = {
4497 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4498
4499 MockRead("HTTP/1.1 200 OK\r\n"),
4500 MockRead("Content-Length: 1\r\n\r\n"),
4501 MockRead(SYNCHRONOUS, "1"),
4502
4503 MockRead("HTTP/1.1 200 OK\r\n"),
4504 MockRead("Content-Length: 2\r\n\r\n"),
4505 MockRead(SYNCHRONOUS, "22"),
4506 };
4507
4508 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4509 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074510 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204511 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204513
4514 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584515 auto trans1 =
4516 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204517
4518 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204520
4521 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014522 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204523
4524 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524525 ASSERT_TRUE(response1);
4526 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 TestLoadTimingNotReusedWithPac(load_timing_info1,
4532 CONNECT_TIMING_HAS_SSL_TIMES);
4533
4534 trans1.reset();
4535
4536 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584537 auto trans2 =
4538 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204539
4540 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204542
4543 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014544 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204545
4546 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524547 ASSERT_TRUE(response2);
4548 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 TestLoadTimingReusedWithPac(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
[email protected]2df19bb2010-08-25 20:13:464561// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014562TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274563 HttpRequestInfo request;
4564 request.method = "GET";
bncce36dca22015-04-21 22:11:234565 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274566
[email protected]2df19bb2010-08-25 20:13:464567 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034568 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514569 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074570 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464572
[email protected]2df19bb2010-08-25 20:13:464573 // Since we have proxy, should use full url
4574 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234575 MockWrite(
4576 "GET http://www.example.org/ HTTP/1.1\r\n"
4577 "Host: www.example.org\r\n"
4578 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464579 };
4580
4581 MockRead data_reads1[] = {
4582 MockRead("HTTP/1.1 200 OK\r\n"),
4583 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4584 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064585 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464586 };
4587
4588 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4589 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074590 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064591 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464593
[email protected]49639fa2011-12-20 23:22:414594 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464595
bnc691fda62016-08-12 00:43:164596 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504597
bnc691fda62016-08-12 00:43:164598 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464600
4601 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014602 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464603
[email protected]58e32bb2013-01-21 18:23:254604 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164605 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254606 TestLoadTimingNotReused(load_timing_info,
4607 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4608
bnc691fda62016-08-12 00:43:164609 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524610 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464611
tbansal2ecbbc72016-10-06 17:15:474612 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464613 EXPECT_TRUE(response->headers->IsKeepAlive());
4614 EXPECT_EQ(200, response->headers->response_code());
4615 EXPECT_EQ(100, response->headers->GetContentLength());
4616 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4617
4618 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524619 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464620}
4621
[email protected]7642b5ae2010-09-01 20:55:174622// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014623TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274624 HttpRequestInfo request;
4625 request.method = "GET";
bncce36dca22015-04-21 22:11:234626 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274627
[email protected]7642b5ae2010-09-01 20:55:174628 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034629 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514630 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074631 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174633
bncce36dca22015-04-21 22:11:234634 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414635 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454636 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414637 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174638
bnc42331402016-07-25 13:36:154639 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414640 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174641 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414642 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174643 };
4644
rch8e6c6c42015-05-01 14:05:134645 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4646 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074647 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174648
[email protected]8ddf8322012-02-23 18:08:064649 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364650 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074651 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174652
[email protected]49639fa2011-12-20 23:22:414653 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174654
bnc691fda62016-08-12 00:43:164655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504656
bnc691fda62016-08-12 00:43:164657 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014658 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174659
4660 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014661 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174662
[email protected]58e32bb2013-01-21 18:23:254663 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164664 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254665 TestLoadTimingNotReused(load_timing_info,
4666 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4667
bnc691fda62016-08-12 00:43:164668 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524669 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474670 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524671 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024672 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174673
4674 std::string response_data;
bnc691fda62016-08-12 00:43:164675 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234676 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174677}
4678
[email protected]1c173852014-06-19 12:51:504679// Verifies that a session which races and wins against the owning transaction
4680// (completing prior to host resolution), doesn't fail the transaction.
4681// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014682TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504683 HttpRequestInfo request;
4684 request.method = "GET";
bncce36dca22015-04-21 22:11:234685 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504686
4687 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034688 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514689 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504690 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504692
bncce36dca22015-04-21 22:11:234693 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414694 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454695 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414696 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504697
bnc42331402016-07-25 13:36:154698 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414699 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504700 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414701 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504702 };
4703
rch8e6c6c42015-05-01 14:05:134704 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4705 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504706 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4707
4708 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364709 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504710 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4711
4712 TestCompletionCallback callback1;
4713
bnc691fda62016-08-12 00:43:164714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504715
4716 // Stall the hostname resolution begun by the transaction.
4717 session_deps_.host_resolver->set_synchronous_mode(false);
4718 session_deps_.host_resolver->set_ondemand_mode(true);
4719
bnc691fda62016-08-12 00:43:164720 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504722
4723 // Race a session to the proxy, which completes first.
4724 session_deps_.host_resolver->set_ondemand_mode(false);
4725 SpdySessionKey key(
4726 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4727 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424728 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504729
4730 // Unstall the resolution begun by the transaction.
4731 session_deps_.host_resolver->set_ondemand_mode(true);
4732 session_deps_.host_resolver->ResolveAllPending();
4733
4734 EXPECT_FALSE(callback1.have_result());
4735 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014736 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504737
bnc691fda62016-08-12 00:43:164738 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524739 ASSERT_TRUE(response);
4740 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024741 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504742
4743 std::string response_data;
bnc691fda62016-08-12 00:43:164744 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504745 EXPECT_EQ(kUploadData, response_data);
4746}
4747
[email protected]dc7bd1c52010-11-12 00:01:134748// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014749TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274750 HttpRequestInfo request;
4751 request.method = "GET";
bncce36dca22015-04-21 22:11:234752 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274753
[email protected]79cb5c12011-09-12 13:12:044754 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034755 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514756 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074757 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134759
[email protected]dc7bd1c52010-11-12 00:01:134760 // The first request will be a bare GET, the second request will be a
4761 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454762 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414763 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494764 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384765 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134766 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464767 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134768 };
bncdf80d44fd2016-07-15 20:27:414769 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4770 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4771 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134772 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414773 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134774 };
4775
4776 // The first response is a 407 proxy authentication challenge, and the second
4777 // response will be a 200 response since the second request includes a valid
4778 // Authorization header.
4779 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464780 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134781 };
bnc42331402016-07-25 13:36:154782 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234783 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414784 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4785 SpdySerializedFrame body_authentication(
4786 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154787 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414788 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134789 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414790 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464791 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414792 CreateMockRead(resp_data, 4),
4793 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134794 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134795 };
4796
rch8e6c6c42015-05-01 14:05:134797 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4798 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074799 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134800
[email protected]8ddf8322012-02-23 18:08:064801 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364802 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074803 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134804
[email protected]49639fa2011-12-20 23:22:414805 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134806
bnc691fda62016-08-12 00:43:164807 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134808
bnc691fda62016-08-12 00:43:164809 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134811
4812 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014813 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134814
bnc691fda62016-08-12 00:43:164815 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134816
wezca1070932016-05-26 20:30:524817 ASSERT_TRUE(response);
4818 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134819 EXPECT_EQ(407, response->headers->response_code());
4820 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434821 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134822
[email protected]49639fa2011-12-20 23:22:414823 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134824
bnc691fda62016-08-12 00:43:164825 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134827
4828 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014829 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134830
bnc691fda62016-08-12 00:43:164831 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134832
wezca1070932016-05-26 20:30:524833 ASSERT_TRUE(response_restart);
4834 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134835 EXPECT_EQ(200, response_restart->headers->response_code());
4836 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524837 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134838}
4839
[email protected]d9da5fe2010-10-13 22:37:164840// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014841TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274842 HttpRequestInfo request;
4843 request.method = "GET";
bncce36dca22015-04-21 22:11:234844 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274845
[email protected]d9da5fe2010-10-13 22:37:164846 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034847 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514848 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074849 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164851
bnc691fda62016-08-12 00:43:164852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164853
bncce36dca22015-04-21 22:11:234854 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414855 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234856 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4857 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164858
bncce36dca22015-04-21 22:11:234859 const char get[] =
4860 "GET / HTTP/1.1\r\n"
4861 "Host: www.example.org\r\n"
4862 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414863 SpdySerializedFrame wrapped_get(
4864 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154865 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164866 const char resp[] = "HTTP/1.1 200 OK\r\n"
4867 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414868 SpdySerializedFrame wrapped_get_resp(
4869 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4870 SpdySerializedFrame wrapped_body(
4871 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4872 SpdySerializedFrame window_update(
4873 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044874
4875 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414876 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4877 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044878 };
4879
[email protected]d9da5fe2010-10-13 22:37:164880 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414881 CreateMockRead(conn_resp, 1, ASYNC),
4882 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4883 CreateMockRead(wrapped_body, 4, ASYNC),
4884 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134885 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164886 };
4887
rch8e6c6c42015-05-01 14:05:134888 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4889 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074890 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164891
[email protected]8ddf8322012-02-23 18:08:064892 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364893 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074894 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064895 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074896 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164897
[email protected]49639fa2011-12-20 23:22:414898 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164899
bnc691fda62016-08-12 00:43:164900 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164902
4903 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014904 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164905
[email protected]58e32bb2013-01-21 18:23:254906 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164907 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254908 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4909
bnc691fda62016-08-12 00:43:164910 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524911 ASSERT_TRUE(response);
4912 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164913 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4914
4915 std::string response_data;
bnc691fda62016-08-12 00:43:164916 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164917 EXPECT_EQ("1234567890", response_data);
4918}
4919
4920// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014921TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4922 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384923
[email protected]cb9bf6ca2011-01-28 13:15:274924 HttpRequestInfo request;
4925 request.method = "GET";
bncce36dca22015-04-21 22:11:234926 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274927
[email protected]d9da5fe2010-10-13 22:37:164928 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034929 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514930 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074931 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094932 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164933
bnc691fda62016-08-12 00:43:164934 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164935
bncce36dca22015-04-21 22:11:234936 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414937 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234938 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4939 // fetch https://www.example.org/ via SPDY
4940 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414941 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494942 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414943 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154944 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414945 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154946 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414947 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024948 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414949 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4950 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024951 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414952 SpdySerializedFrame window_update_get_resp(
4953 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4954 SpdySerializedFrame window_update_body(
4955 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044956
4957 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414958 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4959 CreateMockWrite(window_update_get_resp, 6),
4960 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044961 };
4962
[email protected]d9da5fe2010-10-13 22:37:164963 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414964 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094965 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414966 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4967 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134968 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164969 };
4970
rch32320842015-05-16 15:57:094971 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4972 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074973 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164974
[email protected]8ddf8322012-02-23 18:08:064975 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364976 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074977 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064978 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364979 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074980 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164981
[email protected]49639fa2011-12-20 23:22:414982 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164983
bnc691fda62016-08-12 00:43:164984 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164986
rch32320842015-05-16 15:57:094987 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554988 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094989 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594990 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164991 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014992 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164993
[email protected]58e32bb2013-01-21 18:23:254994 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164995 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254996 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4997
bnc691fda62016-08-12 00:43:164998 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524999 ASSERT_TRUE(response);
5000 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025001 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165002
5003 std::string response_data;
bnc691fda62016-08-12 00:43:165004 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235005 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165006}
5007
5008// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015009TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275010 HttpRequestInfo request;
5011 request.method = "GET";
bncce36dca22015-04-21 22:11:235012 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275013
[email protected]d9da5fe2010-10-13 22:37:165014 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035015 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515016 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075017 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165019
bnc691fda62016-08-12 00:43:165020 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165021
bncce36dca22015-04-21 22:11:235022 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415023 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235024 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415025 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085026 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165027
5028 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415029 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165030 };
5031
bnc42331402016-07-25 13:36:155032 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415033 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165034 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415035 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165036 };
5037
rch8e6c6c42015-05-01 14:05:135038 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5039 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075040 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165041
[email protected]8ddf8322012-02-23 18:08:065042 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365043 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065045 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365046 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075047 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165048
[email protected]49639fa2011-12-20 23:22:415049 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165050
bnc691fda62016-08-12 00:43:165051 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165053
5054 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015055 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165056
ttuttle960fcbf2016-04-19 13:26:325057 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165058}
5059
[email protected]f6c63db52013-02-02 00:35:225060// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5061// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015062TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225063 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5064 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035065 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515066 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075067 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095068 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505069 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225070
5071 HttpRequestInfo request1;
5072 request1.method = "GET";
bncce36dca22015-04-21 22:11:235073 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225074 request1.load_flags = 0;
5075
5076 HttpRequestInfo request2;
5077 request2.method = "GET";
bncce36dca22015-04-21 22:11:235078 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225079 request2.load_flags = 0;
5080
bncce36dca22015-04-21 22:11:235081 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415082 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235083 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155084 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225085
bncce36dca22015-04-21 22:11:235086 // Fetch https://www.example.org/ via HTTP.
5087 const char get1[] =
5088 "GET / HTTP/1.1\r\n"
5089 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225090 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415091 SpdySerializedFrame wrapped_get1(
5092 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225093 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5094 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415095 SpdySerializedFrame wrapped_get_resp1(
5096 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5097 SpdySerializedFrame wrapped_body1(
5098 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5099 SpdySerializedFrame window_update(
5100 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225101
bncce36dca22015-04-21 22:11:235102 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295103 SpdyHeaderBlock connect2_block;
5104 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405105 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155106 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5107 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395108
bnc42331402016-07-25 13:36:155109 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225110
bncce36dca22015-04-21 22:11:235111 // Fetch https://mail.example.org/ via HTTP.
5112 const char get2[] =
5113 "GET / HTTP/1.1\r\n"
5114 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225115 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415116 SpdySerializedFrame wrapped_get2(
5117 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225118 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5119 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415120 SpdySerializedFrame wrapped_get_resp2(
5121 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5122 SpdySerializedFrame wrapped_body2(
5123 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225124
5125 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415126 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5127 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225128 };
5129
5130 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415131 CreateMockRead(conn_resp1, 1, ASYNC),
5132 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5133 CreateMockRead(wrapped_body1, 4, ASYNC),
5134 CreateMockRead(conn_resp2, 6, ASYNC),
5135 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5136 CreateMockRead(wrapped_body2, 9, ASYNC),
5137 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225138 };
5139
mmenke11eb5152015-06-09 14:50:505140 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5141 arraysize(spdy_writes));
5142 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225143
5144 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365145 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225147 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505148 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225149 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505150 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225151
5152 TestCompletionCallback callback;
5153
bnc691fda62016-08-12 00:43:165154 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205155 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015156 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225157
5158 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165159 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225160 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5161
bnc691fda62016-08-12 00:43:165162 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525163 ASSERT_TRUE(response);
5164 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225165 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5166
5167 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295168 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165169 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505170 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225171
bnc691fda62016-08-12 00:43:165172 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205173 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015174 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225175
5176 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165177 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225178 // Even though the SPDY connection is reused, a new tunnelled connection has
5179 // to be created, so the socket's load timing looks like a fresh connection.
5180 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5181
5182 // The requests should have different IDs, since they each are using their own
5183 // separate stream.
5184 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5185
bnc691fda62016-08-12 00:43:165186 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505187 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225188}
5189
5190// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5191// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015192TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225193 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5194 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035195 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515196 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075197 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095198 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505199 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225200
5201 HttpRequestInfo request1;
5202 request1.method = "GET";
bncce36dca22015-04-21 22:11:235203 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225204 request1.load_flags = 0;
5205
5206 HttpRequestInfo request2;
5207 request2.method = "GET";
bncce36dca22015-04-21 22:11:235208 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225209 request2.load_flags = 0;
5210
bncce36dca22015-04-21 22:11:235211 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415212 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235213 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155214 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225215
bncce36dca22015-04-21 22:11:235216 // Fetch https://www.example.org/ via HTTP.
5217 const char get1[] =
5218 "GET / HTTP/1.1\r\n"
5219 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225220 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415221 SpdySerializedFrame wrapped_get1(
5222 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225223 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5224 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415225 SpdySerializedFrame wrapped_get_resp1(
5226 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5227 SpdySerializedFrame wrapped_body1(
5228 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5229 SpdySerializedFrame window_update(
5230 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225231
bncce36dca22015-04-21 22:11:235232 // Fetch https://www.example.org/2 via HTTP.
5233 const char get2[] =
5234 "GET /2 HTTP/1.1\r\n"
5235 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225236 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415237 SpdySerializedFrame wrapped_get2(
5238 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225239 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5240 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415241 SpdySerializedFrame wrapped_get_resp2(
5242 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5243 SpdySerializedFrame wrapped_body2(
5244 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225245
5246 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415247 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5248 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225249 };
5250
5251 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415252 CreateMockRead(conn_resp1, 1, ASYNC),
5253 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465254 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415255 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465256 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415257 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225258 };
5259
mmenke11eb5152015-06-09 14:50:505260 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5261 arraysize(spdy_writes));
5262 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225263
5264 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365265 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225267 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505268 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225269
5270 TestCompletionCallback callback;
5271
bnc87dcefc2017-05-25 12:47:585272 auto trans =
5273 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205274 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015275 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225276
5277 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015278 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225279
5280 LoadTimingInfo load_timing_info;
5281 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5282 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5283
5284 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525285 ASSERT_TRUE(response);
5286 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225287 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5288
5289 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295290 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505291 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225292 trans.reset();
5293
bnc87dcefc2017-05-25 12:47:585294 auto trans2 =
5295 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205296 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225298
[email protected]f6c63db52013-02-02 00:35:225299 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015300 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225301
5302 LoadTimingInfo load_timing_info2;
5303 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5304 TestLoadTimingReused(load_timing_info2);
5305
5306 // The requests should have the same ID.
5307 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5308
[email protected]90499482013-06-01 00:39:505309 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225310}
5311
5312// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5313// Proxy to different servers.
bncd16676a2016-07-20 16:23:015314TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225315 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035316 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515317 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075318 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095319 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505320 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225321
5322 HttpRequestInfo request1;
5323 request1.method = "GET";
bncce36dca22015-04-21 22:11:235324 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225325 request1.load_flags = 0;
5326
5327 HttpRequestInfo request2;
5328 request2.method = "GET";
bncce36dca22015-04-21 22:11:235329 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225330 request2.load_flags = 0;
5331
bncce36dca22015-04-21 22:11:235332 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265333 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235334 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415335 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155336 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5337 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415338 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385339 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225340
bncce36dca22015-04-21 22:11:235341 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265342 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235343 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415344 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155345 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5346 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415347 SpdySerializedFrame body2(
5348 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225349
5350 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415351 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225352 };
5353
5354 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415355 CreateMockRead(get_resp1, 1, ASYNC),
5356 CreateMockRead(body1, 2, ASYNC),
5357 CreateMockRead(get_resp2, 4, ASYNC),
5358 CreateMockRead(body2, 5, ASYNC),
5359 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225360 };
5361
mmenke11eb5152015-06-09 14:50:505362 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5363 arraysize(spdy_writes));
5364 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225365
5366 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365367 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225369
5370 TestCompletionCallback callback;
5371
bnc87dcefc2017-05-25 12:47:585372 auto trans =
5373 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205374 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015375 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225376
5377 LoadTimingInfo load_timing_info;
5378 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5379 TestLoadTimingNotReused(load_timing_info,
5380 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5381
5382 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525383 ASSERT_TRUE(response);
5384 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025385 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225386
5387 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295388 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505389 rv = trans->Read(buf.get(), 256, callback.callback());
5390 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225391 // Delete the first request, so the second one can reuse the socket.
5392 trans.reset();
5393
bnc691fda62016-08-12 00:43:165394 HttpNetworkTransaction trans2(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(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225397
5398 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165399 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225400 TestLoadTimingReused(load_timing_info2);
5401
5402 // The requests should have the same ID.
5403 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5404
bnc691fda62016-08-12 00:43:165405 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505406 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225407}
5408
[email protected]2df19bb2010-08-25 20:13:465409// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015410TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465411 HttpRequestInfo request;
5412 request.method = "GET";
bncce36dca22015-04-21 22:11:235413 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465414 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295415 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465416
[email protected]79cb5c12011-09-12 13:12:045417 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035418 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515419 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075420 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275422
[email protected]2df19bb2010-08-25 20:13:465423 // Since we have proxy, should use full url
5424 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165425 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5426 "Host: www.example.org\r\n"
5427 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465428
bnc691fda62016-08-12 00:43:165429 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235430 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165431 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5432 "Host: www.example.org\r\n"
5433 "Proxy-Connection: keep-alive\r\n"
5434 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465435 };
5436
5437 // The proxy responds to the GET with a 407, using a persistent
5438 // connection.
5439 MockRead data_reads1[] = {
5440 // No credentials.
5441 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5442 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5443 MockRead("Proxy-Connection: keep-alive\r\n"),
5444 MockRead("Content-Length: 0\r\n\r\n"),
5445
5446 MockRead("HTTP/1.1 200 OK\r\n"),
5447 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5448 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065449 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465450 };
5451
5452 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5453 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075454 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065455 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465457
[email protected]49639fa2011-12-20 23:22:415458 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465459
bnc691fda62016-08-12 00:43:165460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505461
bnc691fda62016-08-12 00:43:165462 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465464
5465 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015466 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465467
[email protected]58e32bb2013-01-21 18:23:255468 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165469 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255470 TestLoadTimingNotReused(load_timing_info,
5471 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5472
bnc691fda62016-08-12 00:43:165473 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525474 ASSERT_TRUE(response);
5475 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465476 EXPECT_EQ(407, response->headers->response_code());
5477 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435478 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465479
[email protected]49639fa2011-12-20 23:22:415480 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465481
bnc691fda62016-08-12 00:43:165482 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465484
5485 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015486 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465487
[email protected]58e32bb2013-01-21 18:23:255488 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165489 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255490 // Retrying with HTTP AUTH is considered to be reusing a socket.
5491 TestLoadTimingReused(load_timing_info);
5492
bnc691fda62016-08-12 00:43:165493 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525494 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465495
5496 EXPECT_TRUE(response->headers->IsKeepAlive());
5497 EXPECT_EQ(200, response->headers->response_code());
5498 EXPECT_EQ(100, response->headers->GetContentLength());
5499 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5500
5501 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525502 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465503}
5504
[email protected]23e482282013-06-14 16:08:025505void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085506 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425507 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085508 request.method = "GET";
bncce36dca22015-04-21 22:11:235509 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085510
[email protected]cb9bf6ca2011-01-28 13:15:275511 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035512 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275514
[email protected]c744cf22009-02-27 07:28:085515 // Since we have proxy, should try to establish tunnel.
5516 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175517 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5518 "Host: www.example.org:443\r\n"
5519 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085520 };
5521
5522 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235523 status, MockRead("Content-Length: 10\r\n\r\n"),
5524 // No response body because the test stops reading here.
5525 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085526 };
5527
[email protected]31a2bfe2010-02-09 08:03:395528 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5529 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075530 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085531
[email protected]49639fa2011-12-20 23:22:415532 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085533
bnc691fda62016-08-12 00:43:165534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505535
tfarina42834112016-09-22 13:38:205536 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085538
5539 rv = callback.WaitForResult();
5540 EXPECT_EQ(expected_status, rv);
5541}
5542
[email protected]23e482282013-06-14 16:08:025543void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235544 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085545 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425546 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085547}
5548
bncd16676a2016-07-20 16:23:015549TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085550 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5551}
5552
bncd16676a2016-07-20 16:23:015553TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085554 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5555}
5556
bncd16676a2016-07-20 16:23:015557TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085558 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5559}
5560
bncd16676a2016-07-20 16:23:015561TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085562 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5563}
5564
bncd16676a2016-07-20 16:23:015565TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085566 ConnectStatusHelper(
5567 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5568}
5569
bncd16676a2016-07-20 16:23:015570TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085571 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5572}
5573
bncd16676a2016-07-20 16:23:015574TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085575 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5576}
5577
bncd16676a2016-07-20 16:23:015578TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085579 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5580}
5581
bncd16676a2016-07-20 16:23:015582TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085583 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5584}
5585
bncd16676a2016-07-20 16:23:015586TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085587 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5588}
5589
bncd16676a2016-07-20 16:23:015590TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085591 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5592}
5593
bncd16676a2016-07-20 16:23:015594TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085595 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5596}
5597
bncd16676a2016-07-20 16:23:015598TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085599 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5600}
5601
bncd16676a2016-07-20 16:23:015602TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085603 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5604}
5605
bncd16676a2016-07-20 16:23:015606TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085607 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5608}
5609
bncd16676a2016-07-20 16:23:015610TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085611 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5612}
5613
bncd16676a2016-07-20 16:23:015614TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375615 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5616}
5617
bncd16676a2016-07-20 16:23:015618TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085619 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5620}
5621
bncd16676a2016-07-20 16:23:015622TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085623 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5624}
5625
bncd16676a2016-07-20 16:23:015626TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085627 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5628}
5629
bncd16676a2016-07-20 16:23:015630TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085631 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5632}
5633
bncd16676a2016-07-20 16:23:015634TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085635 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5636}
5637
bncd16676a2016-07-20 16:23:015638TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085639 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5640}
5641
bncd16676a2016-07-20 16:23:015642TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085643 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5644}
5645
bncd16676a2016-07-20 16:23:015646TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085647 ConnectStatusHelperWithExpectedStatus(
5648 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545649 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085650}
5651
bncd16676a2016-07-20 16:23:015652TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085653 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5654}
5655
bncd16676a2016-07-20 16:23:015656TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085657 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5658}
5659
bncd16676a2016-07-20 16:23:015660TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085661 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5662}
5663
bncd16676a2016-07-20 16:23:015664TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085665 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5666}
5667
bncd16676a2016-07-20 16:23:015668TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085669 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5670}
5671
bncd16676a2016-07-20 16:23:015672TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085673 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5674}
5675
bncd16676a2016-07-20 16:23:015676TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085677 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5678}
5679
bncd16676a2016-07-20 16:23:015680TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085681 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5682}
5683
bncd16676a2016-07-20 16:23:015684TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085685 ConnectStatusHelper(
5686 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5687}
5688
bncd16676a2016-07-20 16:23:015689TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085690 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5691}
5692
bncd16676a2016-07-20 16:23:015693TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085694 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5695}
5696
bncd16676a2016-07-20 16:23:015697TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085698 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5699}
5700
bncd16676a2016-07-20 16:23:015701TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085702 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5703}
5704
bncd16676a2016-07-20 16:23:015705TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085706 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5707}
5708
bncd16676a2016-07-20 16:23:015709TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085710 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5711}
5712
bncd16676a2016-07-20 16:23:015713TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085714 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5715}
5716
[email protected]038e9a32008-10-08 22:40:165717// Test the flow when both the proxy server AND origin server require
5718// authentication. Again, this uses basic auth for both since that is
5719// the simplest to mock.
bncd16676a2016-07-20 16:23:015720TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275721 HttpRequestInfo request;
5722 request.method = "GET";
bncce36dca22015-04-21 22:11:235723 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275724
[email protected]038e9a32008-10-08 22:40:165725 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035726 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075728
bnc691fda62016-08-12 00:43:165729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165730
[email protected]f9ee6b52008-11-08 06:46:235731 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235732 MockWrite(
5733 "GET http://www.example.org/ HTTP/1.1\r\n"
5734 "Host: www.example.org\r\n"
5735 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235736 };
5737
[email protected]038e9a32008-10-08 22:40:165738 MockRead data_reads1[] = {
5739 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5740 // Give a couple authenticate options (only the middle one is actually
5741 // supported).
[email protected]22927ad2009-09-21 19:56:195742 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165743 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5744 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5745 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5746 // Large content-length -- won't matter, as connection will be reset.
5747 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065748 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165749 };
5750
bnc691fda62016-08-12 00:43:165751 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165752 // request we should be issuing -- the final header line contains the
5753 // proxy's credentials.
5754 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235755 MockWrite(
5756 "GET http://www.example.org/ HTTP/1.1\r\n"
5757 "Host: www.example.org\r\n"
5758 "Proxy-Connection: keep-alive\r\n"
5759 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165760 };
5761
5762 // Now the proxy server lets the request pass through to origin server.
5763 // The origin server responds with a 401.
5764 MockRead data_reads2[] = {
5765 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5766 // Note: We are using the same realm-name as the proxy server. This is
5767 // completely valid, as realms are unique across hosts.
5768 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5769 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5770 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065771 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165772 };
5773
bnc691fda62016-08-12 00:43:165774 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165775 // the credentials for both the proxy and origin server.
5776 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235777 MockWrite(
5778 "GET http://www.example.org/ HTTP/1.1\r\n"
5779 "Host: www.example.org\r\n"
5780 "Proxy-Connection: keep-alive\r\n"
5781 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5782 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165783 };
5784
5785 // Lastly we get the desired content.
5786 MockRead data_reads3[] = {
5787 MockRead("HTTP/1.0 200 OK\r\n"),
5788 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5789 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065790 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165791 };
5792
[email protected]31a2bfe2010-02-09 08:03:395793 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5794 data_writes1, arraysize(data_writes1));
5795 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5796 data_writes2, arraysize(data_writes2));
5797 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5798 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075799 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5800 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5801 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165802
[email protected]49639fa2011-12-20 23:22:415803 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165804
tfarina42834112016-09-22 13:38:205805 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165807
5808 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015809 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165810
bnc691fda62016-08-12 00:43:165811 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525812 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045813 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165814
[email protected]49639fa2011-12-20 23:22:415815 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165816
bnc691fda62016-08-12 00:43:165817 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165819
5820 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015821 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165822
bnc691fda62016-08-12 00:43:165823 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525824 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045825 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165826
[email protected]49639fa2011-12-20 23:22:415827 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165828
bnc691fda62016-08-12 00:43:165829 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5830 callback3.callback());
robpercival214763f2016-07-01 23:27:015831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165832
5833 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015834 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165835
bnc691fda62016-08-12 00:43:165836 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525837 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165838 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165839}
[email protected]4ddaf2502008-10-23 18:26:195840
[email protected]ea9dc9a2009-09-05 00:43:325841// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5842// can't hook into its internals to cause it to generate predictable NTLM
5843// authorization headers.
5844#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295845// The NTLM authentication unit tests were generated by capturing the HTTP
5846// requests and responses using Fiddler 2 and inspecting the generated random
5847// bytes in the debugger.
5848
5849// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015850TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425851 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245852 request.method = "GET";
5853 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545854
5855 // Ensure load is not disrupted by flags which suppress behaviour specific
5856 // to other auth schemes.
5857 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245858
[email protected]cb9bf6ca2011-01-28 13:15:275859 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5860 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275862
[email protected]3f918782009-02-28 01:29:245863 MockWrite data_writes1[] = {
5864 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5865 "Host: 172.22.68.17\r\n"
5866 "Connection: keep-alive\r\n\r\n"),
5867 };
5868
5869 MockRead data_reads1[] = {
5870 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045871 // Negotiate and NTLM are often requested together. However, we only want
5872 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5873 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245874 MockRead("WWW-Authenticate: NTLM\r\n"),
5875 MockRead("Connection: close\r\n"),
5876 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365877 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245878 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065879 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245880 };
5881
5882 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165883 // After restarting with a null identity, this is the
5884 // request we should be issuing -- the final header line contains a Type
5885 // 1 message.
5886 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5887 "Host: 172.22.68.17\r\n"
5888 "Connection: keep-alive\r\n"
5889 "Authorization: NTLM "
5890 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245891
bnc691fda62016-08-12 00:43:165892 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5893 // (the credentials for the origin server). The second request continues
5894 // on the same connection.
5895 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5896 "Host: 172.22.68.17\r\n"
5897 "Connection: keep-alive\r\n"
5898 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5899 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5900 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5901 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5902 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245903 };
5904
5905 MockRead data_reads2[] = {
5906 // The origin server responds with a Type 2 message.
5907 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5908 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295909 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245910 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5911 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5912 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5913 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5914 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5915 "BtAAAAAAA=\r\n"),
5916 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365917 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245918 MockRead("You are not authorized to view this page\r\n"),
5919
5920 // Lastly we get the desired content.
5921 MockRead("HTTP/1.1 200 OK\r\n"),
5922 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5923 MockRead("Content-Length: 13\r\n\r\n"),
5924 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065925 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245926 };
5927
[email protected]31a2bfe2010-02-09 08:03:395928 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5929 data_writes1, arraysize(data_writes1));
5930 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5931 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5933 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245934
[email protected]49639fa2011-12-20 23:22:415935 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245936
bnc691fda62016-08-12 00:43:165937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505938
tfarina42834112016-09-22 13:38:205939 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245941
5942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015943 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245944
bnc691fda62016-08-12 00:43:165945 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225946
bnc691fda62016-08-12 00:43:165947 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525948 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045949 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245950
[email protected]49639fa2011-12-20 23:22:415951 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255952
bnc691fda62016-08-12 00:43:165953 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5954 callback2.callback());
robpercival214763f2016-07-01 23:27:015955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255956
5957 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015958 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255959
bnc691fda62016-08-12 00:43:165960 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255961
bnc691fda62016-08-12 00:43:165962 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525963 ASSERT_TRUE(response);
5964 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255965
[email protected]49639fa2011-12-20 23:22:415966 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245967
bnc691fda62016-08-12 00:43:165968 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015969 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245970
[email protected]0757e7702009-03-27 04:00:225971 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015972 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245973
bnc691fda62016-08-12 00:43:165974 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525975 ASSERT_TRUE(response);
5976 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245977 EXPECT_EQ(13, response->headers->GetContentLength());
5978}
5979
[email protected]385a4672009-03-11 22:21:295980// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015981TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425982 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295983 request.method = "GET";
5984 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:295985
[email protected]cb9bf6ca2011-01-28 13:15:275986 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5987 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095988 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275989
[email protected]385a4672009-03-11 22:21:295990 MockWrite data_writes1[] = {
5991 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5992 "Host: 172.22.68.17\r\n"
5993 "Connection: keep-alive\r\n\r\n"),
5994 };
5995
5996 MockRead data_reads1[] = {
5997 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045998 // Negotiate and NTLM are often requested together. However, we only want
5999 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6000 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296001 MockRead("WWW-Authenticate: NTLM\r\n"),
6002 MockRead("Connection: close\r\n"),
6003 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366004 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296005 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066006 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296007 };
6008
6009 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166010 // After restarting with a null identity, this is the
6011 // request we should be issuing -- the final header line contains a Type
6012 // 1 message.
6013 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6014 "Host: 172.22.68.17\r\n"
6015 "Connection: keep-alive\r\n"
6016 "Authorization: NTLM "
6017 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296018
bnc691fda62016-08-12 00:43:166019 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6020 // (the credentials for the origin server). The second request continues
6021 // on the same connection.
6022 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6023 "Host: 172.22.68.17\r\n"
6024 "Connection: keep-alive\r\n"
6025 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6026 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6027 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6028 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6029 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296030 };
6031
6032 MockRead data_reads2[] = {
6033 // The origin server responds with a Type 2 message.
6034 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6035 MockRead("WWW-Authenticate: NTLM "
6036 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6037 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6038 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6039 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6040 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6041 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6042 "BtAAAAAAA=\r\n"),
6043 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366044 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296045 MockRead("You are not authorized to view this page\r\n"),
6046
6047 // Wrong password.
6048 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296049 MockRead("WWW-Authenticate: NTLM\r\n"),
6050 MockRead("Connection: close\r\n"),
6051 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366052 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296053 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066054 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296055 };
6056
6057 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166058 // After restarting with a null identity, this is the
6059 // request we should be issuing -- the final header line contains a Type
6060 // 1 message.
6061 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6062 "Host: 172.22.68.17\r\n"
6063 "Connection: keep-alive\r\n"
6064 "Authorization: NTLM "
6065 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296066
bnc691fda62016-08-12 00:43:166067 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6068 // (the credentials for the origin server). The second request continues
6069 // on the same connection.
6070 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6071 "Host: 172.22.68.17\r\n"
6072 "Connection: keep-alive\r\n"
6073 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6074 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6075 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6076 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6077 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296078 };
6079
6080 MockRead data_reads3[] = {
6081 // The origin server responds with a Type 2 message.
6082 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6083 MockRead("WWW-Authenticate: NTLM "
6084 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6085 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6086 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6087 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6088 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6089 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6090 "BtAAAAAAA=\r\n"),
6091 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366092 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296093 MockRead("You are not authorized to view this page\r\n"),
6094
6095 // Lastly we get the desired content.
6096 MockRead("HTTP/1.1 200 OK\r\n"),
6097 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6098 MockRead("Content-Length: 13\r\n\r\n"),
6099 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066100 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296101 };
6102
[email protected]31a2bfe2010-02-09 08:03:396103 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6104 data_writes1, arraysize(data_writes1));
6105 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6106 data_writes2, arraysize(data_writes2));
6107 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6108 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076109 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6110 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6111 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296112
[email protected]49639fa2011-12-20 23:22:416113 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296114
bnc691fda62016-08-12 00:43:166115 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506116
tfarina42834112016-09-22 13:38:206117 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296119
6120 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016121 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296122
bnc691fda62016-08-12 00:43:166123 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296124
bnc691fda62016-08-12 00:43:166125 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526126 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046127 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296128
[email protected]49639fa2011-12-20 23:22:416129 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296130
[email protected]0757e7702009-03-27 04:00:226131 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166132 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6133 callback2.callback());
robpercival214763f2016-07-01 23:27:016134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296135
[email protected]10af5fe72011-01-31 16:17:256136 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016137 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296138
bnc691fda62016-08-12 00:43:166139 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416140 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166141 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256143 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016144 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166145 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226146
bnc691fda62016-08-12 00:43:166147 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526148 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046149 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226150
[email protected]49639fa2011-12-20 23:22:416151 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226152
6153 // Now enter the right password.
bnc691fda62016-08-12 00:43:166154 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6155 callback4.callback());
robpercival214763f2016-07-01 23:27:016156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256157
6158 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016159 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256160
bnc691fda62016-08-12 00:43:166161 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256162
[email protected]49639fa2011-12-20 23:22:416163 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256164
6165 // One more roundtrip
bnc691fda62016-08-12 00:43:166166 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016167 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226168
6169 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016170 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226171
bnc691fda62016-08-12 00:43:166172 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526173 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296174 EXPECT_EQ(13, response->headers->GetContentLength());
6175}
[email protected]ea9dc9a2009-09-05 00:43:326176#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296177
[email protected]4ddaf2502008-10-23 18:26:196178// Test reading a server response which has only headers, and no body.
6179// After some maximum number of bytes is consumed, the transaction should
6180// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016181TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426182 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196183 request.method = "GET";
bncce36dca22015-04-21 22:11:236184 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196185
danakj1fd259a02016-04-16 03:17:096186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166187 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276188
[email protected]b75b7b2f2009-10-06 00:54:536189 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436190 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536191 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196192
6193 MockRead data_reads[] = {
6194 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066195 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196196 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066197 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196198 };
[email protected]31a2bfe2010-02-09 08:03:396199 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076200 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196201
[email protected]49639fa2011-12-20 23:22:416202 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196203
tfarina42834112016-09-22 13:38:206204 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196206
6207 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016208 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196209}
[email protected]f4e426b2008-11-05 00:24:496210
6211// Make sure that we don't try to reuse a TCPClientSocket when failing to
6212// establish tunnel.
6213// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016214TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276215 HttpRequestInfo request;
6216 request.method = "GET";
bncce36dca22015-04-21 22:11:236217 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276218
[email protected]f4e426b2008-11-05 00:24:496219 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036220 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016221
danakj1fd259a02016-04-16 03:17:096222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496223
bnc87dcefc2017-05-25 12:47:586224 auto trans =
6225 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496226
[email protected]f4e426b2008-11-05 00:24:496227 // Since we have proxy, should try to establish tunnel.
6228 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176229 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6230 "Host: www.example.org:443\r\n"
6231 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496232 };
6233
[email protected]77848d12008-11-14 00:00:226234 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496235 // connection. Usually a proxy would return 501 (not implemented),
6236 // or 200 (tunnel established).
6237 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236238 MockRead("HTTP/1.1 404 Not Found\r\n"),
6239 MockRead("Content-Length: 10\r\n\r\n"),
6240 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496241 };
6242
[email protected]31a2bfe2010-02-09 08:03:396243 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6244 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076245 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496246
[email protected]49639fa2011-12-20 23:22:416247 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496248
tfarina42834112016-09-22 13:38:206249 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496251
6252 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016253 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496254
[email protected]b4404c02009-04-10 16:38:526255 // Empty the current queue. This is necessary because idle sockets are
6256 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556257 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526258
[email protected]f4e426b2008-11-05 00:24:496259 // We now check to make sure the TCPClientSocket was not added back to
6260 // the pool.
[email protected]90499482013-06-01 00:39:506261 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496262 trans.reset();
fdoray92e35a72016-06-10 15:54:556263 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496264 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506265 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496266}
[email protected]372d34a2008-11-05 21:30:516267
[email protected]1b157c02009-04-21 01:55:406268// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016269TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426270 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406271 request.method = "GET";
bncce36dca22015-04-21 22:11:236272 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406273
danakj1fd259a02016-04-16 03:17:096274 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276275
bnc691fda62016-08-12 00:43:166276 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276277
[email protected]1b157c02009-04-21 01:55:406278 MockRead data_reads[] = {
6279 // A part of the response body is received with the response headers.
6280 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6281 // The rest of the response body is received in two parts.
6282 MockRead("lo"),
6283 MockRead(" world"),
6284 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066285 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406286 };
6287
[email protected]31a2bfe2010-02-09 08:03:396288 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406290
[email protected]49639fa2011-12-20 23:22:416291 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406292
tfarina42834112016-09-22 13:38:206293 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016294 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406295
6296 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016297 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406298
bnc691fda62016-08-12 00:43:166299 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526300 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406301
wezca1070932016-05-26 20:30:526302 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406303 std::string status_line = response->headers->GetStatusLine();
6304 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6305
[email protected]90499482013-06-01 00:39:506306 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406307
6308 std::string response_data;
bnc691fda62016-08-12 00:43:166309 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016310 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406311 EXPECT_EQ("hello world", response_data);
6312
6313 // Empty the current queue. This is necessary because idle sockets are
6314 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556315 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406316
6317 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506318 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406319}
6320
[email protected]76a505b2010-08-25 06:23:006321// Make sure that we recycle a SSL socket after reading all of the response
6322// body.
bncd16676a2016-07-20 16:23:016323TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006324 HttpRequestInfo request;
6325 request.method = "GET";
bncce36dca22015-04-21 22:11:236326 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006327
6328 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236329 MockWrite(
6330 "GET / HTTP/1.1\r\n"
6331 "Host: www.example.org\r\n"
6332 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006333 };
6334
6335 MockRead data_reads[] = {
6336 MockRead("HTTP/1.1 200 OK\r\n"),
6337 MockRead("Content-Length: 11\r\n\r\n"),
6338 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066339 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006340 };
6341
[email protected]8ddf8322012-02-23 18:08:066342 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076343 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006344
6345 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6346 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076347 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006348
[email protected]49639fa2011-12-20 23:22:416349 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006350
danakj1fd259a02016-04-16 03:17:096351 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166352 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006353
tfarina42834112016-09-22 13:38:206354 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006355
robpercival214763f2016-07-01 23:27:016356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6357 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006358
bnc691fda62016-08-12 00:43:166359 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526360 ASSERT_TRUE(response);
6361 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006362 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6363
[email protected]90499482013-06-01 00:39:506364 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006365
6366 std::string response_data;
bnc691fda62016-08-12 00:43:166367 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016368 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006369 EXPECT_EQ("hello world", response_data);
6370
6371 // Empty the current queue. This is necessary because idle sockets are
6372 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556373 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006374
6375 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506376 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006377}
6378
6379// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6380// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016381TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006382 HttpRequestInfo request;
6383 request.method = "GET";
bncce36dca22015-04-21 22:11:236384 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006385
6386 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236387 MockWrite(
6388 "GET / HTTP/1.1\r\n"
6389 "Host: www.example.org\r\n"
6390 "Connection: keep-alive\r\n\r\n"),
6391 MockWrite(
6392 "GET / HTTP/1.1\r\n"
6393 "Host: www.example.org\r\n"
6394 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006395 };
6396
6397 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426398 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6399 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006400
[email protected]8ddf8322012-02-23 18:08:066401 SSLSocketDataProvider ssl(ASYNC, OK);
6402 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6404 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006405
6406 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6407 data_writes, arraysize(data_writes));
6408 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6409 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076410 session_deps_.socket_factory->AddSocketDataProvider(&data);
6411 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006412
[email protected]49639fa2011-12-20 23:22:416413 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006414
danakj1fd259a02016-04-16 03:17:096415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586416 auto trans =
6417 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006418
tfarina42834112016-09-22 13:38:206419 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006420
robpercival214763f2016-07-01 23:27:016421 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6422 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006423
6424 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526425 ASSERT_TRUE(response);
6426 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006427 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6428
[email protected]90499482013-06-01 00:39:506429 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006430
6431 std::string response_data;
6432 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016433 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006434 EXPECT_EQ("hello world", response_data);
6435
6436 // Empty the current queue. This is necessary because idle sockets are
6437 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556438 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006439
6440 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506441 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006442
6443 // Now start the second transaction, which should reuse the previous socket.
6444
bnc87dcefc2017-05-25 12:47:586445 trans =
6446 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006447
tfarina42834112016-09-22 13:38:206448 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006449
robpercival214763f2016-07-01 23:27:016450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6451 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006452
6453 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526454 ASSERT_TRUE(response);
6455 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6457
[email protected]90499482013-06-01 00:39:506458 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006459
6460 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016461 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006462 EXPECT_EQ("hello world", response_data);
6463
6464 // Empty the current queue. This is necessary because idle sockets are
6465 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556466 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006467
6468 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506469 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006470}
6471
maksim.sisov0adf8592016-07-15 06:25:566472// Grab a socket, use it, and put it back into the pool. Then, make
6473// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016474TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566475 HttpRequestInfo request;
6476 request.method = "GET";
6477 request.url = GURL("http://www.example.org/");
6478 request.load_flags = 0;
6479
6480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6481
bnc691fda62016-08-12 00:43:166482 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566483
6484 MockRead data_reads[] = {
6485 // A part of the response body is received with the response headers.
6486 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6487 // The rest of the response body is received in two parts.
6488 MockRead("lo"), MockRead(" world"),
6489 MockRead("junk"), // Should not be read!!
6490 MockRead(SYNCHRONOUS, OK),
6491 };
6492
6493 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6494 session_deps_.socket_factory->AddSocketDataProvider(&data);
6495
6496 TestCompletionCallback callback;
6497
tfarina42834112016-09-22 13:38:206498 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566499 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6500
6501 EXPECT_THAT(callback.GetResult(rv), IsOk());
6502
bnc691fda62016-08-12 00:43:166503 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566504 ASSERT_TRUE(response);
6505 EXPECT_TRUE(response->headers);
6506 std::string status_line = response->headers->GetStatusLine();
6507 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6508
6509 // Make memory critical notification and ensure the transaction still has been
6510 // operating right.
6511 base::MemoryPressureListener::NotifyMemoryPressure(
6512 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6513 base::RunLoop().RunUntilIdle();
6514
6515 // Socket should not be flushed as long as it is not idle.
6516 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6517
6518 std::string response_data;
bnc691fda62016-08-12 00:43:166519 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566520 EXPECT_THAT(rv, IsOk());
6521 EXPECT_EQ("hello world", response_data);
6522
6523 // Empty the current queue. This is necessary because idle sockets are
6524 // added to the connection pool asynchronously with a PostTask.
6525 base::RunLoop().RunUntilIdle();
6526
6527 // We now check to make sure the socket was added back to the pool.
6528 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6529
6530 // Idle sockets should be flushed now.
6531 base::MemoryPressureListener::NotifyMemoryPressure(
6532 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6533 base::RunLoop().RunUntilIdle();
6534
6535 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6536}
6537
6538// Grab an SSL socket, use it, and put it back into the pool. Then, make
6539// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016540TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566541 HttpRequestInfo request;
6542 request.method = "GET";
6543 request.url = GURL("https://www.example.org/");
6544 request.load_flags = 0;
6545
6546 MockWrite data_writes[] = {
6547 MockWrite("GET / HTTP/1.1\r\n"
6548 "Host: www.example.org\r\n"
6549 "Connection: keep-alive\r\n\r\n"),
6550 };
6551
6552 MockRead data_reads[] = {
6553 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6554 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6555
6556 SSLSocketDataProvider ssl(ASYNC, OK);
6557 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6558
6559 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6560 arraysize(data_writes));
6561 session_deps_.socket_factory->AddSocketDataProvider(&data);
6562
6563 TestCompletionCallback callback;
6564
6565 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166566 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566567
6568 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206569 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566570
6571 EXPECT_THAT(callback.GetResult(rv), IsOk());
6572
bnc691fda62016-08-12 00:43:166573 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566574 ASSERT_TRUE(response);
6575 ASSERT_TRUE(response->headers);
6576 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6577
6578 // Make memory critical notification and ensure the transaction still has been
6579 // operating right.
6580 base::MemoryPressureListener::NotifyMemoryPressure(
6581 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6582 base::RunLoop().RunUntilIdle();
6583
6584 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6585
6586 std::string response_data;
bnc691fda62016-08-12 00:43:166587 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566588 EXPECT_THAT(rv, IsOk());
6589 EXPECT_EQ("hello world", response_data);
6590
6591 // Empty the current queue. This is necessary because idle sockets are
6592 // added to the connection pool asynchronously with a PostTask.
6593 base::RunLoop().RunUntilIdle();
6594
6595 // We now check to make sure the socket was added back to the pool.
6596 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6597
6598 // Make memory notification once again and ensure idle socket is closed.
6599 base::MemoryPressureListener::NotifyMemoryPressure(
6600 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6601 base::RunLoop().RunUntilIdle();
6602
6603 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6604}
6605
[email protected]b4404c02009-04-10 16:38:526606// Make sure that we recycle a socket after a zero-length response.
6607// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016608TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426609 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526610 request.method = "GET";
bncce36dca22015-04-21 22:11:236611 request.url = GURL(
6612 "http://www.example.org/csi?v=3&s=web&action=&"
6613 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6614 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6615 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526616
danakj1fd259a02016-04-16 03:17:096617 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276618
[email protected]b4404c02009-04-10 16:38:526619 MockRead data_reads[] = {
6620 MockRead("HTTP/1.1 204 No Content\r\n"
6621 "Content-Length: 0\r\n"
6622 "Content-Type: text/html\r\n\r\n"),
6623 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066624 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526625 };
6626
[email protected]31a2bfe2010-02-09 08:03:396627 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076628 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526629
mmenkecc2298e2015-12-07 18:20:186630 // Transaction must be created after the MockReads, so it's destroyed before
6631 // them.
bnc691fda62016-08-12 00:43:166632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186633
[email protected]49639fa2011-12-20 23:22:416634 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526635
tfarina42834112016-09-22 13:38:206636 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526638
6639 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016640 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526641
bnc691fda62016-08-12 00:43:166642 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526643 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526644
wezca1070932016-05-26 20:30:526645 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526646 std::string status_line = response->headers->GetStatusLine();
6647 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6648
[email protected]90499482013-06-01 00:39:506649 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526650
6651 std::string response_data;
bnc691fda62016-08-12 00:43:166652 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016653 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526654 EXPECT_EQ("", response_data);
6655
6656 // Empty the current queue. This is necessary because idle sockets are
6657 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556658 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526659
6660 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506661 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526662}
6663
bncd16676a2016-07-20 16:23:016664TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096665 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226666 element_readers.push_back(
ricea2deef682016-09-09 08:04:076667 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226668 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276669
[email protected]1c773ea12009-04-28 19:58:426670 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516671 // Transaction 1: a GET request that succeeds. The socket is recycled
6672 // after use.
6673 request[0].method = "GET";
6674 request[0].url = GURL("http://www.google.com/");
6675 request[0].load_flags = 0;
6676 // Transaction 2: a POST request. Reuses the socket kept alive from
6677 // transaction 1. The first attempts fails when writing the POST data.
6678 // This causes the transaction to retry with a new socket. The second
6679 // attempt succeeds.
6680 request[1].method = "POST";
6681 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276682 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516683 request[1].load_flags = 0;
6684
danakj1fd259a02016-04-16 03:17:096685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516686
6687 // The first socket is used for transaction 1 and the first attempt of
6688 // transaction 2.
6689
6690 // The response of transaction 1.
6691 MockRead data_reads1[] = {
6692 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6693 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066694 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516695 };
6696 // The mock write results of transaction 1 and the first attempt of
6697 // transaction 2.
6698 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066699 MockWrite(SYNCHRONOUS, 64), // GET
6700 MockWrite(SYNCHRONOUS, 93), // POST
6701 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516702 };
[email protected]31a2bfe2010-02-09 08:03:396703 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6704 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516705
6706 // The second socket is used for the second attempt of transaction 2.
6707
6708 // The response of transaction 2.
6709 MockRead data_reads2[] = {
6710 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6711 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066712 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516713 };
6714 // The mock write results of the second attempt of transaction 2.
6715 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066716 MockWrite(SYNCHRONOUS, 93), // POST
6717 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516718 };
[email protected]31a2bfe2010-02-09 08:03:396719 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6720 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516721
[email protected]bb88e1d32013-05-03 23:11:076722 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6723 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516724
thestig9d3bb0c2015-01-24 00:49:516725 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516726 "hello world", "welcome"
6727 };
6728
6729 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516731
[email protected]49639fa2011-12-20 23:22:416732 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516733
tfarina42834112016-09-22 13:38:206734 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516736
6737 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016738 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516739
bnc691fda62016-08-12 00:43:166740 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526741 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516742
wezca1070932016-05-26 20:30:526743 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516744 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6745
6746 std::string response_data;
bnc691fda62016-08-12 00:43:166747 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016748 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516749 EXPECT_EQ(kExpectedResponseData[i], response_data);
6750 }
6751}
[email protected]f9ee6b52008-11-08 06:46:236752
6753// Test the request-challenge-retry sequence for basic auth when there is
6754// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166755// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016756TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426757 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236758 request.method = "GET";
bncce36dca22015-04-21 22:11:236759 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416760 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296761
danakj1fd259a02016-04-16 03:17:096762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166763 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276764
[email protected]a97cca42009-08-14 01:00:296765 // The password contains an escaped character -- for this test to pass it
6766 // will need to be unescaped by HttpNetworkTransaction.
6767 EXPECT_EQ("b%40r", request.url.password());
6768
[email protected]f9ee6b52008-11-08 06:46:236769 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236770 MockWrite(
6771 "GET / HTTP/1.1\r\n"
6772 "Host: www.example.org\r\n"
6773 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236774 };
6775
6776 MockRead data_reads1[] = {
6777 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6778 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6779 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066780 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236781 };
6782
[email protected]2262e3a2012-05-22 16:08:166783 // After the challenge above, the transaction will be restarted using the
6784 // identity from the url (foo, b@r) to answer the challenge.
6785 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236786 MockWrite(
6787 "GET / HTTP/1.1\r\n"
6788 "Host: www.example.org\r\n"
6789 "Connection: keep-alive\r\n"
6790 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166791 };
6792
6793 MockRead data_reads2[] = {
6794 MockRead("HTTP/1.0 200 OK\r\n"),
6795 MockRead("Content-Length: 100\r\n\r\n"),
6796 MockRead(SYNCHRONOUS, OK),
6797 };
6798
[email protected]31a2bfe2010-02-09 08:03:396799 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6800 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166801 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6802 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076803 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6804 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236805
[email protected]49639fa2011-12-20 23:22:416806 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206807 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236809 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016810 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166811 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166812
6813 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166814 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166816 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016817 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166818 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226819
bnc691fda62016-08-12 00:43:166820 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526821 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166822
6823 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526824 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166825
6826 EXPECT_EQ(100, response->headers->GetContentLength());
6827
6828 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556829 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166830}
6831
6832// Test the request-challenge-retry sequence for basic auth when there is an
6833// incorrect identity in the URL. The identity from the URL should be used only
6834// once.
bncd16676a2016-07-20 16:23:016835TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166836 HttpRequestInfo request;
6837 request.method = "GET";
6838 // Note: the URL has a username:password in it. The password "baz" is
6839 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236840 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166841
6842 request.load_flags = LOAD_NORMAL;
6843
danakj1fd259a02016-04-16 03:17:096844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166845 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166846
6847 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236848 MockWrite(
6849 "GET / HTTP/1.1\r\n"
6850 "Host: www.example.org\r\n"
6851 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166852 };
6853
6854 MockRead data_reads1[] = {
6855 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6856 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6857 MockRead("Content-Length: 10\r\n\r\n"),
6858 MockRead(SYNCHRONOUS, ERR_FAILED),
6859 };
6860
6861 // After the challenge above, the transaction will be restarted using the
6862 // identity from the url (foo, baz) to answer the challenge.
6863 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236864 MockWrite(
6865 "GET / HTTP/1.1\r\n"
6866 "Host: www.example.org\r\n"
6867 "Connection: keep-alive\r\n"
6868 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166869 };
6870
6871 MockRead data_reads2[] = {
6872 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6873 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6874 MockRead("Content-Length: 10\r\n\r\n"),
6875 MockRead(SYNCHRONOUS, ERR_FAILED),
6876 };
6877
6878 // After the challenge above, the transaction will be restarted using the
6879 // identity supplied by the user (foo, bar) to answer the challenge.
6880 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236881 MockWrite(
6882 "GET / HTTP/1.1\r\n"
6883 "Host: www.example.org\r\n"
6884 "Connection: keep-alive\r\n"
6885 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166886 };
6887
6888 MockRead data_reads3[] = {
6889 MockRead("HTTP/1.0 200 OK\r\n"),
6890 MockRead("Content-Length: 100\r\n\r\n"),
6891 MockRead(SYNCHRONOUS, OK),
6892 };
6893
6894 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6895 data_writes1, arraysize(data_writes1));
6896 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6897 data_writes2, arraysize(data_writes2));
6898 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6899 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076900 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6901 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6902 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166903
6904 TestCompletionCallback callback1;
6905
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]2262e3a2012-05-22 16:08:166908
6909 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016910 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166911
bnc691fda62016-08-12 00:43:166912 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166913 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166914 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166916 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016917 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166918 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166919
bnc691fda62016-08-12 00:43:166920 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526921 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166922 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6923
6924 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166925 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166927 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016928 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166929 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166930
bnc691fda62016-08-12 00:43:166931 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526932 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166933
6934 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526935 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166936
6937 EXPECT_EQ(100, response->headers->GetContentLength());
6938
[email protected]ea9dc9a2009-09-05 00:43:326939 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556940 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326941}
6942
[email protected]2217aa22013-10-11 03:03:546943
6944// Test the request-challenge-retry sequence for basic auth when there is a
6945// correct identity in the URL, but its use is being suppressed. The identity
6946// from the URL should never be used.
bncd16676a2016-07-20 16:23:016947TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546948 HttpRequestInfo request;
6949 request.method = "GET";
bncce36dca22015-04-21 22:11:236950 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546951 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6952
danakj1fd259a02016-04-16 03:17:096953 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546955
6956 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236957 MockWrite(
6958 "GET / HTTP/1.1\r\n"
6959 "Host: www.example.org\r\n"
6960 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546961 };
6962
6963 MockRead data_reads1[] = {
6964 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6965 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6966 MockRead("Content-Length: 10\r\n\r\n"),
6967 MockRead(SYNCHRONOUS, ERR_FAILED),
6968 };
6969
6970 // After the challenge above, the transaction will be restarted using the
6971 // identity supplied by the user, not the one in the URL, to answer the
6972 // challenge.
6973 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236974 MockWrite(
6975 "GET / HTTP/1.1\r\n"
6976 "Host: www.example.org\r\n"
6977 "Connection: keep-alive\r\n"
6978 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546979 };
6980
6981 MockRead data_reads3[] = {
6982 MockRead("HTTP/1.0 200 OK\r\n"),
6983 MockRead("Content-Length: 100\r\n\r\n"),
6984 MockRead(SYNCHRONOUS, OK),
6985 };
6986
6987 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6988 data_writes1, arraysize(data_writes1));
6989 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6990 data_writes3, arraysize(data_writes3));
6991 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6992 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6993
6994 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206995 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:546997 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016998 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166999 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547000
bnc691fda62016-08-12 00:43:167001 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527002 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547003 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7004
7005 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167006 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547008 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017009 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167010 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547011
bnc691fda62016-08-12 00:43:167012 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527013 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547014
7015 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527016 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547017 EXPECT_EQ(100, response->headers->GetContentLength());
7018
7019 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557020 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547021}
7022
[email protected]f9ee6b52008-11-08 06:46:237023// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017024TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097025 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237026
7027 // Transaction 1: authenticate (foo, bar) on MyRealm1
7028 {
[email protected]1c773ea12009-04-28 19:58:427029 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237030 request.method = "GET";
bncce36dca22015-04-21 22:11:237031 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237032
bnc691fda62016-08-12 00:43:167033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277034
[email protected]f9ee6b52008-11-08 06:46:237035 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237036 MockWrite(
7037 "GET /x/y/z HTTP/1.1\r\n"
7038 "Host: www.example.org\r\n"
7039 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237040 };
7041
7042 MockRead data_reads1[] = {
7043 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7044 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7045 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067046 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237047 };
7048
7049 // Resend with authorization (username=foo, password=bar)
7050 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237051 MockWrite(
7052 "GET /x/y/z HTTP/1.1\r\n"
7053 "Host: www.example.org\r\n"
7054 "Connection: keep-alive\r\n"
7055 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237056 };
7057
7058 // Sever accepts the authorization.
7059 MockRead data_reads2[] = {
7060 MockRead("HTTP/1.0 200 OK\r\n"),
7061 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067062 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237063 };
7064
[email protected]31a2bfe2010-02-09 08:03:397065 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7066 data_writes1, arraysize(data_writes1));
7067 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7068 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077069 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7070 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237071
[email protected]49639fa2011-12-20 23:22:417072 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237073
tfarina42834112016-09-22 13:38:207074 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017075 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237076
7077 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017078 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237079
bnc691fda62016-08-12 00:43:167080 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527081 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047082 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237083
[email protected]49639fa2011-12-20 23:22:417084 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237085
bnc691fda62016-08-12 00:43:167086 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7087 callback2.callback());
robpercival214763f2016-07-01 23:27:017088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237089
7090 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017091 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237092
bnc691fda62016-08-12 00:43:167093 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527094 ASSERT_TRUE(response);
7095 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237096 EXPECT_EQ(100, response->headers->GetContentLength());
7097 }
7098
7099 // ------------------------------------------------------------------------
7100
7101 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7102 {
[email protected]1c773ea12009-04-28 19:58:427103 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237104 request.method = "GET";
7105 // Note that Transaction 1 was at /x/y/z, so this is in the same
7106 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237107 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237108
bnc691fda62016-08-12 00:43:167109 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277110
[email protected]f9ee6b52008-11-08 06:46:237111 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237112 MockWrite(
7113 "GET /x/y/a/b HTTP/1.1\r\n"
7114 "Host: www.example.org\r\n"
7115 "Connection: keep-alive\r\n"
7116 // Send preemptive authorization for MyRealm1
7117 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237118 };
7119
7120 // The server didn't like the preemptive authorization, and
7121 // challenges us for a different realm (MyRealm2).
7122 MockRead data_reads1[] = {
7123 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7124 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7125 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067126 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237127 };
7128
7129 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7130 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237131 MockWrite(
7132 "GET /x/y/a/b HTTP/1.1\r\n"
7133 "Host: www.example.org\r\n"
7134 "Connection: keep-alive\r\n"
7135 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237136 };
7137
7138 // Sever accepts the authorization.
7139 MockRead data_reads2[] = {
7140 MockRead("HTTP/1.0 200 OK\r\n"),
7141 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067142 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237143 };
7144
[email protected]31a2bfe2010-02-09 08:03:397145 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7146 data_writes1, arraysize(data_writes1));
7147 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7148 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077149 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7150 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237151
[email protected]49639fa2011-12-20 23:22:417152 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237153
tfarina42834112016-09-22 13:38:207154 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237156
7157 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017158 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237159
bnc691fda62016-08-12 00:43:167160 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527161 ASSERT_TRUE(response);
7162 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047163 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437164 EXPECT_EQ("http://www.example.org",
7165 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047166 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197167 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237168
[email protected]49639fa2011-12-20 23:22:417169 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237170
bnc691fda62016-08-12 00:43:167171 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7172 callback2.callback());
robpercival214763f2016-07-01 23:27:017173 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237174
7175 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017176 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237177
bnc691fda62016-08-12 00:43:167178 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527179 ASSERT_TRUE(response);
7180 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237181 EXPECT_EQ(100, response->headers->GetContentLength());
7182 }
7183
7184 // ------------------------------------------------------------------------
7185
7186 // Transaction 3: Resend a request in MyRealm's protection space --
7187 // succeed with preemptive authorization.
7188 {
[email protected]1c773ea12009-04-28 19:58:427189 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237190 request.method = "GET";
bncce36dca22015-04-21 22:11:237191 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237192
bnc691fda62016-08-12 00:43:167193 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277194
[email protected]f9ee6b52008-11-08 06:46:237195 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237196 MockWrite(
7197 "GET /x/y/z2 HTTP/1.1\r\n"
7198 "Host: www.example.org\r\n"
7199 "Connection: keep-alive\r\n"
7200 // The authorization for MyRealm1 gets sent preemptively
7201 // (since the url is in the same protection space)
7202 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237203 };
7204
7205 // Sever accepts the preemptive authorization
7206 MockRead data_reads1[] = {
7207 MockRead("HTTP/1.0 200 OK\r\n"),
7208 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067209 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237210 };
7211
[email protected]31a2bfe2010-02-09 08:03:397212 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7213 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077214 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237215
[email protected]49639fa2011-12-20 23:22:417216 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237217
tfarina42834112016-09-22 13:38:207218 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237220
7221 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017222 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237223
bnc691fda62016-08-12 00:43:167224 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527225 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237226
wezca1070932016-05-26 20:30:527227 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237228 EXPECT_EQ(100, response->headers->GetContentLength());
7229 }
7230
7231 // ------------------------------------------------------------------------
7232
7233 // Transaction 4: request another URL in MyRealm (however the
7234 // url is not known to belong to the protection space, so no pre-auth).
7235 {
[email protected]1c773ea12009-04-28 19:58:427236 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237237 request.method = "GET";
bncce36dca22015-04-21 22:11:237238 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237239
bnc691fda62016-08-12 00:43:167240 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277241
[email protected]f9ee6b52008-11-08 06:46:237242 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237243 MockWrite(
7244 "GET /x/1 HTTP/1.1\r\n"
7245 "Host: www.example.org\r\n"
7246 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237247 };
7248
7249 MockRead data_reads1[] = {
7250 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7251 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7252 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067253 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237254 };
7255
7256 // Resend with authorization from MyRealm's cache.
7257 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237258 MockWrite(
7259 "GET /x/1 HTTP/1.1\r\n"
7260 "Host: www.example.org\r\n"
7261 "Connection: keep-alive\r\n"
7262 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237263 };
7264
7265 // Sever accepts the authorization.
7266 MockRead data_reads2[] = {
7267 MockRead("HTTP/1.0 200 OK\r\n"),
7268 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067269 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237270 };
7271
[email protected]31a2bfe2010-02-09 08:03:397272 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7273 data_writes1, arraysize(data_writes1));
7274 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7275 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077276 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7277 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237278
[email protected]49639fa2011-12-20 23:22:417279 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237280
tfarina42834112016-09-22 13:38:207281 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237283
7284 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017285 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237286
bnc691fda62016-08-12 00:43:167287 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417288 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167289 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017290 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227291 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017292 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167293 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227294
bnc691fda62016-08-12 00:43:167295 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527296 ASSERT_TRUE(response);
7297 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237298 EXPECT_EQ(100, response->headers->GetContentLength());
7299 }
7300
7301 // ------------------------------------------------------------------------
7302
7303 // Transaction 5: request a URL in MyRealm, but the server rejects the
7304 // cached identity. Should invalidate and re-prompt.
7305 {
[email protected]1c773ea12009-04-28 19:58:427306 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237307 request.method = "GET";
bncce36dca22015-04-21 22:11:237308 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237309
bnc691fda62016-08-12 00:43:167310 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277311
[email protected]f9ee6b52008-11-08 06:46:237312 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237313 MockWrite(
7314 "GET /p/q/t HTTP/1.1\r\n"
7315 "Host: www.example.org\r\n"
7316 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237317 };
7318
7319 MockRead data_reads1[] = {
7320 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7321 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7322 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067323 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237324 };
7325
7326 // Resend with authorization from cache for MyRealm.
7327 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237328 MockWrite(
7329 "GET /p/q/t HTTP/1.1\r\n"
7330 "Host: www.example.org\r\n"
7331 "Connection: keep-alive\r\n"
7332 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237333 };
7334
7335 // Sever rejects the authorization.
7336 MockRead data_reads2[] = {
7337 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7338 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7339 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067340 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237341 };
7342
7343 // At this point we should prompt for new credentials for MyRealm.
7344 // Restart with username=foo3, password=foo4.
7345 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237346 MockWrite(
7347 "GET /p/q/t HTTP/1.1\r\n"
7348 "Host: www.example.org\r\n"
7349 "Connection: keep-alive\r\n"
7350 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237351 };
7352
7353 // Sever accepts the authorization.
7354 MockRead data_reads3[] = {
7355 MockRead("HTTP/1.0 200 OK\r\n"),
7356 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067357 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237358 };
7359
[email protected]31a2bfe2010-02-09 08:03:397360 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7361 data_writes1, arraysize(data_writes1));
7362 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7363 data_writes2, arraysize(data_writes2));
7364 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7365 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077366 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7367 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7368 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237369
[email protected]49639fa2011-12-20 23:22:417370 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237371
tfarina42834112016-09-22 13:38:207372 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237374
7375 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017376 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237377
bnc691fda62016-08-12 00:43:167378 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417379 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167380 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017381 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227382 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017383 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167384 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227385
bnc691fda62016-08-12 00:43:167386 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527387 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047388 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237389
[email protected]49639fa2011-12-20 23:22:417390 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237391
bnc691fda62016-08-12 00:43:167392 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7393 callback3.callback());
robpercival214763f2016-07-01 23:27:017394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237395
[email protected]0757e7702009-03-27 04:00:227396 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017397 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237398
bnc691fda62016-08-12 00:43:167399 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527400 ASSERT_TRUE(response);
7401 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237402 EXPECT_EQ(100, response->headers->GetContentLength());
7403 }
7404}
[email protected]89ceba9a2009-03-21 03:46:067405
[email protected]3c32c5f2010-05-18 15:18:127406// Tests that nonce count increments when multiple auth attempts
7407// are started with the same nonce.
bncd16676a2016-07-20 16:23:017408TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447409 HttpAuthHandlerDigest::Factory* digest_factory =
7410 new HttpAuthHandlerDigest::Factory();
7411 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7412 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7413 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077414 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127416
7417 // Transaction 1: authenticate (foo, bar) on MyRealm1
7418 {
[email protected]3c32c5f2010-05-18 15:18:127419 HttpRequestInfo request;
7420 request.method = "GET";
bncce36dca22015-04-21 22:11:237421 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127422
bnc691fda62016-08-12 00:43:167423 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277424
[email protected]3c32c5f2010-05-18 15:18:127425 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237426 MockWrite(
7427 "GET /x/y/z HTTP/1.1\r\n"
7428 "Host: www.example.org\r\n"
7429 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127430 };
7431
7432 MockRead data_reads1[] = {
7433 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7434 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7435 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067436 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127437 };
7438
7439 // Resend with authorization (username=foo, password=bar)
7440 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237441 MockWrite(
7442 "GET /x/y/z HTTP/1.1\r\n"
7443 "Host: www.example.org\r\n"
7444 "Connection: keep-alive\r\n"
7445 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7446 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7447 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7448 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127449 };
7450
7451 // Sever accepts the authorization.
7452 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087453 MockRead("HTTP/1.0 200 OK\r\n"),
7454 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127455 };
7456
7457 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7458 data_writes1, arraysize(data_writes1));
7459 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7460 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077461 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7462 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127463
[email protected]49639fa2011-12-20 23:22:417464 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127465
tfarina42834112016-09-22 13:38:207466 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127468
7469 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017470 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127471
bnc691fda62016-08-12 00:43:167472 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527473 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047474 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127475
[email protected]49639fa2011-12-20 23:22:417476 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127477
bnc691fda62016-08-12 00:43:167478 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7479 callback2.callback());
robpercival214763f2016-07-01 23:27:017480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127481
7482 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017483 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127484
bnc691fda62016-08-12 00:43:167485 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527486 ASSERT_TRUE(response);
7487 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127488 }
7489
7490 // ------------------------------------------------------------------------
7491
7492 // Transaction 2: Request another resource in digestive's protection space.
7493 // This will preemptively add an Authorization header which should have an
7494 // "nc" value of 2 (as compared to 1 in the first use.
7495 {
[email protected]3c32c5f2010-05-18 15:18:127496 HttpRequestInfo request;
7497 request.method = "GET";
7498 // Note that Transaction 1 was at /x/y/z, so this is in the same
7499 // protection space as digest.
bncce36dca22015-04-21 22:11:237500 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127501
bnc691fda62016-08-12 00:43:167502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277503
[email protected]3c32c5f2010-05-18 15:18:127504 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237505 MockWrite(
7506 "GET /x/y/a/b HTTP/1.1\r\n"
7507 "Host: www.example.org\r\n"
7508 "Connection: keep-alive\r\n"
7509 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7510 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7511 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7512 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127513 };
7514
7515 // Sever accepts the authorization.
7516 MockRead data_reads1[] = {
7517 MockRead("HTTP/1.0 200 OK\r\n"),
7518 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067519 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127520 };
7521
7522 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7523 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077524 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127525
[email protected]49639fa2011-12-20 23:22:417526 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127527
tfarina42834112016-09-22 13:38:207528 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017529 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127530
7531 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017532 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127533
bnc691fda62016-08-12 00:43:167534 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527535 ASSERT_TRUE(response);
7536 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127537 }
7538}
7539
[email protected]89ceba9a2009-03-21 03:46:067540// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017541TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067542 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097543 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167544 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067545
7546 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167547 trans.read_buf_ = new IOBuffer(15);
7548 trans.read_buf_len_ = 15;
7549 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067550
7551 // Setup state in response_
bnc691fda62016-08-12 00:43:167552 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577553 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087554 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577555 response->response_time = base::Time::Now();
7556 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067557
7558 { // Setup state for response_.vary_data
7559 HttpRequestInfo request;
7560 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7561 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277562 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437563 request.extra_headers.SetHeader("Foo", "1");
7564 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507565 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067566 }
7567
7568 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167569 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067570
7571 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167572 EXPECT_FALSE(trans.read_buf_);
7573 EXPECT_EQ(0, trans.read_buf_len_);
7574 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527575 EXPECT_FALSE(response->auth_challenge);
7576 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047577 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087578 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577579 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067580}
7581
[email protected]bacff652009-03-31 17:50:337582// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017583TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337584 HttpRequestInfo request;
7585 request.method = "GET";
bncce36dca22015-04-21 22:11:237586 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337587
danakj1fd259a02016-04-16 03:17:097588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277590
[email protected]bacff652009-03-31 17:50:337591 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237592 MockWrite(
7593 "GET / HTTP/1.1\r\n"
7594 "Host: www.example.org\r\n"
7595 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337596 };
7597
7598 MockRead data_reads[] = {
7599 MockRead("HTTP/1.0 200 OK\r\n"),
7600 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7601 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067602 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337603 };
7604
[email protected]5ecc992a42009-11-11 01:41:597605 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397606 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7607 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067608 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7609 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337610
[email protected]bb88e1d32013-05-03 23:11:077611 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7612 session_deps_.socket_factory->AddSocketDataProvider(&data);
7613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337615
[email protected]49639fa2011-12-20 23:22:417616 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337617
tfarina42834112016-09-22 13:38:207618 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337620
7621 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017622 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337623
bnc691fda62016-08-12 00:43:167624 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337626
7627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017628 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337629
bnc691fda62016-08-12 00:43:167630 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337631
wezca1070932016-05-26 20:30:527632 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337633 EXPECT_EQ(100, response->headers->GetContentLength());
7634}
7635
7636// Test HTTPS connections to a site with a bad certificate, going through a
7637// proxy
bncd16676a2016-07-20 16:23:017638TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037639 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337640
7641 HttpRequestInfo request;
7642 request.method = "GET";
bncce36dca22015-04-21 22:11:237643 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337644
7645 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177646 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7647 "Host: www.example.org:443\r\n"
7648 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337649 };
7650
7651 MockRead proxy_reads[] = {
7652 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067653 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337654 };
7655
7656 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177657 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7658 "Host: www.example.org:443\r\n"
7659 "Proxy-Connection: keep-alive\r\n\r\n"),
7660 MockWrite("GET / HTTP/1.1\r\n"
7661 "Host: www.example.org\r\n"
7662 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337663 };
7664
7665 MockRead data_reads[] = {
7666 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7667 MockRead("HTTP/1.0 200 OK\r\n"),
7668 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7669 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067670 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337671 };
7672
[email protected]31a2bfe2010-02-09 08:03:397673 StaticSocketDataProvider ssl_bad_certificate(
7674 proxy_reads, arraysize(proxy_reads),
7675 proxy_writes, arraysize(proxy_writes));
7676 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7677 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067678 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7679 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337680
[email protected]bb88e1d32013-05-03 23:11:077681 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7682 session_deps_.socket_factory->AddSocketDataProvider(&data);
7683 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7684 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337685
[email protected]49639fa2011-12-20 23:22:417686 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337687
7688 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077689 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337690
danakj1fd259a02016-04-16 03:17:097691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167692 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337693
tfarina42834112016-09-22 13:38:207694 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337696
7697 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017698 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337699
bnc691fda62016-08-12 00:43:167700 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337702
7703 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017704 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337705
bnc691fda62016-08-12 00:43:167706 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337707
wezca1070932016-05-26 20:30:527708 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337709 EXPECT_EQ(100, response->headers->GetContentLength());
7710 }
7711}
7712
[email protected]2df19bb2010-08-25 20:13:467713
7714// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017715TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037716 session_deps_.proxy_service =
7717 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517718 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077719 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467720
7721 HttpRequestInfo request;
7722 request.method = "GET";
bncce36dca22015-04-21 22:11:237723 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467724
7725 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177726 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7727 "Host: www.example.org:443\r\n"
7728 "Proxy-Connection: keep-alive\r\n\r\n"),
7729 MockWrite("GET / HTTP/1.1\r\n"
7730 "Host: www.example.org\r\n"
7731 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467732 };
7733
7734 MockRead data_reads[] = {
7735 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7736 MockRead("HTTP/1.1 200 OK\r\n"),
7737 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7738 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067739 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467740 };
7741
7742 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7743 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067744 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7745 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467746
[email protected]bb88e1d32013-05-03 23:11:077747 session_deps_.socket_factory->AddSocketDataProvider(&data);
7748 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7749 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467750
[email protected]49639fa2011-12-20 23:22:417751 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467752
danakj1fd259a02016-04-16 03:17:097753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467755
tfarina42834112016-09-22 13:38:207756 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467758
7759 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017760 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167761 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467762
wezca1070932016-05-26 20:30:527763 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467764
tbansal2ecbbc72016-10-06 17:15:477765 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467766 EXPECT_TRUE(response->headers->IsKeepAlive());
7767 EXPECT_EQ(200, response->headers->response_code());
7768 EXPECT_EQ(100, response->headers->GetContentLength());
7769 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207770
7771 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167772 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207773 TestLoadTimingNotReusedWithPac(load_timing_info,
7774 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467775}
7776
[email protected]511f6f52010-12-17 03:58:297777// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017778TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037779 session_deps_.proxy_service =
7780 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517781 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077782 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297783
7784 HttpRequestInfo request;
7785 request.method = "GET";
bncce36dca22015-04-21 22:11:237786 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297787
7788 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177789 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7790 "Host: www.example.org:443\r\n"
7791 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297792 };
7793
7794 MockRead data_reads[] = {
7795 MockRead("HTTP/1.1 302 Redirect\r\n"),
7796 MockRead("Location: http://login.example.com/\r\n"),
7797 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067798 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297799 };
7800
7801 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7802 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067803 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297804
[email protected]bb88e1d32013-05-03 23:11:077805 session_deps_.socket_factory->AddSocketDataProvider(&data);
7806 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297807
[email protected]49639fa2011-12-20 23:22:417808 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297809
danakj1fd259a02016-04-16 03:17:097810 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297812
tfarina42834112016-09-22 13:38:207813 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297815
7816 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017817 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167818 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297819
wezca1070932016-05-26 20:30:527820 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297821
7822 EXPECT_EQ(302, response->headers->response_code());
7823 std::string url;
7824 EXPECT_TRUE(response->headers->IsRedirect(&url));
7825 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207826
7827 // In the case of redirects from proxies, HttpNetworkTransaction returns
7828 // timing for the proxy connection instead of the connection to the host,
7829 // and no send / receive times.
7830 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7831 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167832 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207833
7834 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197835 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207836
7837 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7838 EXPECT_LE(load_timing_info.proxy_resolve_start,
7839 load_timing_info.proxy_resolve_end);
7840 EXPECT_LE(load_timing_info.proxy_resolve_end,
7841 load_timing_info.connect_timing.connect_start);
7842 ExpectConnectTimingHasTimes(
7843 load_timing_info.connect_timing,
7844 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7845
7846 EXPECT_TRUE(load_timing_info.send_start.is_null());
7847 EXPECT_TRUE(load_timing_info.send_end.is_null());
7848 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297849}
7850
7851// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017852TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037853 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297854
7855 HttpRequestInfo request;
7856 request.method = "GET";
bncce36dca22015-04-21 22:11:237857 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297858
bncdf80d44fd2016-07-15 20:27:417859 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237860 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417861 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:087862 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297863 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417864 CreateMockWrite(conn, 0, SYNCHRONOUS),
7865 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297866 };
7867
7868 static const char* const kExtraHeaders[] = {
7869 "location",
7870 "http://login.example.com/",
7871 };
bnc42331402016-07-25 13:36:157872 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237873 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297874 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417875 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297876 };
7877
rch8e6c6c42015-05-01 14:05:137878 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7879 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067880 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367881 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297882
[email protected]bb88e1d32013-05-03 23:11:077883 session_deps_.socket_factory->AddSocketDataProvider(&data);
7884 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297885
[email protected]49639fa2011-12-20 23:22:417886 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297887
danakj1fd259a02016-04-16 03:17:097888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297890
tfarina42834112016-09-22 13:38:207891 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017892 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297893
7894 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017895 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167896 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297897
wezca1070932016-05-26 20:30:527898 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297899
7900 EXPECT_EQ(302, response->headers->response_code());
7901 std::string url;
7902 EXPECT_TRUE(response->headers->IsRedirect(&url));
7903 EXPECT_EQ("http://login.example.com/", url);
7904}
7905
[email protected]4eddbc732012-08-09 05:40:177906// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017907TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037908 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297909
7910 HttpRequestInfo request;
7911 request.method = "GET";
bncce36dca22015-04-21 22:11:237912 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297913
7914 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177915 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7916 "Host: www.example.org:443\r\n"
7917 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297918 };
7919
7920 MockRead data_reads[] = {
7921 MockRead("HTTP/1.1 404 Not Found\r\n"),
7922 MockRead("Content-Length: 23\r\n\r\n"),
7923 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067924 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297925 };
7926
7927 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7928 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067929 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297930
[email protected]bb88e1d32013-05-03 23:11:077931 session_deps_.socket_factory->AddSocketDataProvider(&data);
7932 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297933
[email protected]49639fa2011-12-20 23:22:417934 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297935
danakj1fd259a02016-04-16 03:17:097936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297938
tfarina42834112016-09-22 13:38:207939 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297941
7942 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017943 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297944
ttuttle960fcbf2016-04-19 13:26:327945 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297946}
7947
[email protected]4eddbc732012-08-09 05:40:177948// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017949TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037950 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297951
7952 HttpRequestInfo request;
7953 request.method = "GET";
bncce36dca22015-04-21 22:11:237954 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297955
bncdf80d44fd2016-07-15 20:27:417956 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237957 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417958 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:087959 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:297960 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417961 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297962 };
7963
7964 static const char* const kExtraHeaders[] = {
7965 "location",
7966 "http://login.example.com/",
7967 };
bnc42331402016-07-25 13:36:157968 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237969 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:417970 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557971 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297972 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417973 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137974 MockRead(ASYNC, 0, 4), // 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, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297995
ttuttle960fcbf2016-04-19 13:26:327996 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297997}
7998
[email protected]0c5fb722012-02-28 11:50:357999// Test the request-challenge-retry sequence for basic auth, through
8000// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018001TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358002 HttpRequestInfo request;
8003 request.method = "GET";
bncce36dca22015-04-21 22:11:238004 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358005 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298006 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358007
8008 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038009 session_deps_.proxy_service =
8010 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518011 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078012 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358014
8015 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418016 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238017 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418018 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088019 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388020 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358021
bnc691fda62016-08-12 00:43:168022 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358023 // be issuing -- the final header line contains the credentials.
8024 const char* const kAuthCredentials[] = {
8025 "proxy-authorization", "Basic Zm9vOmJhcg==",
8026 };
bncdf80d44fd2016-07-15 20:27:418027 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348028 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238029 HostPortPair("www.example.org", 443)));
8030 // fetch https://www.example.org/ via HTTP
8031 const char get[] =
8032 "GET / HTTP/1.1\r\n"
8033 "Host: www.example.org\r\n"
8034 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418035 SpdySerializedFrame wrapped_get(
8036 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358037
8038 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418039 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8040 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358041 };
8042
8043 // The proxy responds to the connect with a 407, using a persistent
8044 // connection.
thestig9d3bb0c2015-01-24 00:49:518045 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358046 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358047 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8048 };
bnc42331402016-07-25 13:36:158049 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418050 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358051
bnc42331402016-07-25 13:36:158052 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358053 const char resp[] = "HTTP/1.1 200 OK\r\n"
8054 "Content-Length: 5\r\n\r\n";
8055
bncdf80d44fd2016-07-15 20:27:418056 SpdySerializedFrame wrapped_get_resp(
8057 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8058 SpdySerializedFrame wrapped_body(
8059 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358060 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418061 CreateMockRead(conn_auth_resp, 1, ASYNC),
8062 CreateMockRead(conn_resp, 4, ASYNC),
8063 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8064 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138065 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358066 };
8067
rch8e6c6c42015-05-01 14:05:138068 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8069 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078070 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358071 // Negotiate SPDY to the proxy
8072 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368073 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078074 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358075 // Vanilla SSL to the server
8076 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078077 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358078
8079 TestCompletionCallback callback1;
8080
bnc87dcefc2017-05-25 12:47:588081 auto trans =
8082 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358083
8084 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358086
8087 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018088 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468089 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358090 log.GetEntries(&entries);
8091 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008092 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8093 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358094 ExpectLogContainsSomewhere(
8095 entries, pos,
mikecirone8b85c432016-09-08 19:11:008096 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8097 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358098
8099 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528100 ASSERT_TRUE(response);
8101 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358102 EXPECT_EQ(407, response->headers->response_code());
8103 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528104 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438105 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358106
8107 TestCompletionCallback callback2;
8108
8109 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8110 callback2.callback());
robpercival214763f2016-07-01 23:27:018111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358112
8113 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018114 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358115
8116 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528117 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358118
8119 EXPECT_TRUE(response->headers->IsKeepAlive());
8120 EXPECT_EQ(200, response->headers->response_code());
8121 EXPECT_EQ(5, response->headers->GetContentLength());
8122 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8123
8124 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528125 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358126
[email protected]029c83b62013-01-24 05:28:208127 LoadTimingInfo load_timing_info;
8128 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8129 TestLoadTimingNotReusedWithPac(load_timing_info,
8130 CONNECT_TIMING_HAS_SSL_TIMES);
8131
[email protected]0c5fb722012-02-28 11:50:358132 trans.reset();
8133 session->CloseAllConnections();
8134}
8135
[email protected]7c6f7ba2012-04-03 04:09:298136// Test that an explicitly trusted SPDY proxy can push a resource from an
8137// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018138TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158139 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588140 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158141 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8142 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298143 HttpRequestInfo request;
8144 HttpRequestInfo push_request;
8145
[email protected]7c6f7ba2012-04-03 04:09:298146 request.method = "GET";
bncce36dca22015-04-21 22:11:238147 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298148 push_request.method = "GET";
8149 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8150
tbansal28e68f82016-02-04 02:56:158151 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038152 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158153 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518154 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078155 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508156
inlinechan894515af2016-12-09 02:40:108157 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508158
danakj1fd259a02016-04-16 03:17:098159 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298160
bncdf80d44fd2016-07-15 20:27:418161 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458162 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358163 SpdySerializedFrame stream2_priority(
8164 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298165
8166 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418167 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358168 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298169 };
8170
bncdf80d44fd2016-07-15 20:27:418171 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158172 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298173
bncdf80d44fd2016-07-15 20:27:418174 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298175
bncdf80d44fd2016-07-15 20:27:418176 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558177 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438178 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418179 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8180 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298181
8182 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418183 CreateMockRead(stream1_reply, 1, ASYNC),
8184 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358185 CreateMockRead(stream1_body, 4, ASYNC),
8186 CreateMockRead(stream2_body, 5, ASYNC),
8187 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298188 };
8189
rch8e6c6c42015-05-01 14:05:138190 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8191 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078192 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298193 // Negotiate SPDY to the proxy
8194 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368195 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078196 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298197
bnc87dcefc2017-05-25 12:47:588198 auto trans =
8199 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298200 TestCompletionCallback callback;
8201 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298203
8204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018205 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298206 const HttpResponseInfo* response = trans->GetResponseInfo();
8207
bnc87dcefc2017-05-25 12:47:588208 auto push_trans =
8209 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508210 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018211 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298212
8213 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018214 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298215 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8216
wezca1070932016-05-26 20:30:528217 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298218 EXPECT_TRUE(response->headers->IsKeepAlive());
8219
8220 EXPECT_EQ(200, response->headers->response_code());
8221 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8222
8223 std::string response_data;
8224 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018225 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298226 EXPECT_EQ("hello!", response_data);
8227
[email protected]029c83b62013-01-24 05:28:208228 LoadTimingInfo load_timing_info;
8229 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8230 TestLoadTimingNotReusedWithPac(load_timing_info,
8231 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8232
[email protected]7c6f7ba2012-04-03 04:09:298233 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528234 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298235 EXPECT_EQ(200, push_response->headers->response_code());
8236
8237 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018238 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298239 EXPECT_EQ("pushed", response_data);
8240
[email protected]029c83b62013-01-24 05:28:208241 LoadTimingInfo push_load_timing_info;
8242 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8243 TestLoadTimingReusedWithPac(push_load_timing_info);
8244 // The transactions should share a socket ID, despite being for different
8245 // origins.
8246 EXPECT_EQ(load_timing_info.socket_log_id,
8247 push_load_timing_info.socket_log_id);
8248
[email protected]7c6f7ba2012-04-03 04:09:298249 trans.reset();
8250 push_trans.reset();
8251 session->CloseAllConnections();
8252}
8253
[email protected]8c843192012-04-05 07:15:008254// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018255TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158256 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588257 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158258 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8259 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008260 HttpRequestInfo request;
8261
8262 request.method = "GET";
bncce36dca22015-04-21 22:11:238263 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008264
tbansal28e68f82016-02-04 02:56:158265 session_deps_.proxy_service =
8266 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518267 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078268 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508269
8270 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108271 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508272
danakj1fd259a02016-04-16 03:17:098273 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008274
bncdf80d44fd2016-07-15 20:27:418275 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458276 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008277
bncdf80d44fd2016-07-15 20:27:418278 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088279 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008280
8281 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418282 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008283 };
8284
bncdf80d44fd2016-07-15 20:27:418285 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158286 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008287
bncdf80d44fd2016-07-15 20:27:418288 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008289
bncdf80d44fd2016-07-15 20:27:418290 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558291 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008292
8293 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418294 CreateMockRead(stream1_reply, 1, ASYNC),
8295 CreateMockRead(stream2_syn, 2, ASYNC),
8296 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598297 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008298 };
8299
rch8e6c6c42015-05-01 14:05:138300 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8301 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078302 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008303 // Negotiate SPDY to the proxy
8304 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368305 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078306 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008307
bnc87dcefc2017-05-25 12:47:588308 auto trans =
8309 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008310 TestCompletionCallback callback;
8311 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008313
8314 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018315 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008316 const HttpResponseInfo* response = trans->GetResponseInfo();
8317
wezca1070932016-05-26 20:30:528318 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008319 EXPECT_TRUE(response->headers->IsKeepAlive());
8320
8321 EXPECT_EQ(200, response->headers->response_code());
8322 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8323
8324 std::string response_data;
8325 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018326 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008327 EXPECT_EQ("hello!", response_data);
8328
8329 trans.reset();
8330 session->CloseAllConnections();
8331}
8332
tbansal8ef1d3e2016-02-03 04:05:428333// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8334// resources.
bncd16676a2016-07-20 16:23:018335TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158336 // Configure the proxy delegate to allow cross-origin SPDY pushes.
bnc87dcefc2017-05-25 12:47:588337 auto proxy_delegate = base::MakeUnique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158338 proxy_delegate->set_trusted_spdy_proxy(
8339 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8340
tbansal8ef1d3e2016-02-03 04:05:428341 HttpRequestInfo request;
8342
8343 request.method = "GET";
8344 request.url = GURL("http://www.example.org/");
8345
8346 // Configure against https proxy server "myproxy:70".
8347 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8348 BoundTestNetLog log;
8349 session_deps_.net_log = log.bound().net_log();
8350
8351 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108352 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428353
danakj1fd259a02016-04-16 03:17:098354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428355
bncdf80d44fd2016-07-15 20:27:418356 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458357 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358358 SpdySerializedFrame stream2_priority(
8359 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428360
8361 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418362 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358363 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428364 };
8365
bncdf80d44fd2016-07-15 20:27:418366 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158367 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428368
bncdf80d44fd2016-07-15 20:27:418369 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498370 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8371
bncdf80d44fd2016-07-15 20:27:418372 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428373
bncdf80d44fd2016-07-15 20:27:418374 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158375 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428376
bncdf80d44fd2016-07-15 20:27:418377 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428378
8379 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418380 CreateMockRead(stream1_reply, 1, ASYNC),
8381 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358382 CreateMockRead(stream1_body, 4, ASYNC),
8383 CreateMockRead(stream2_body, 5, ASYNC),
8384 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428385 };
8386
8387 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8388 arraysize(spdy_writes));
8389 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8390 // Negotiate SPDY to the proxy
8391 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368392 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428393 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8394
bnc87dcefc2017-05-25 12:47:588395 auto trans =
8396 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428397 TestCompletionCallback callback;
8398 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428400
8401 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018402 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428403 const HttpResponseInfo* response = trans->GetResponseInfo();
8404
wezca1070932016-05-26 20:30:528405 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428406 EXPECT_TRUE(response->headers->IsKeepAlive());
8407
8408 EXPECT_EQ(200, response->headers->response_code());
8409 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8410
8411 std::string response_data;
8412 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018413 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428414 EXPECT_EQ("hello!", response_data);
8415
8416 trans.reset();
8417 session->CloseAllConnections();
8418}
8419
[email protected]2df19bb2010-08-25 20:13:468420// Test HTTPS connections to a site with a bad certificate, going through an
8421// HTTPS proxy
bncd16676a2016-07-20 16:23:018422TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038423 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468424
8425 HttpRequestInfo request;
8426 request.method = "GET";
bncce36dca22015-04-21 22:11:238427 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468428
8429 // Attempt to fetch the URL from a server with a bad cert
8430 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178431 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8432 "Host: www.example.org:443\r\n"
8433 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468434 };
8435
8436 MockRead bad_cert_reads[] = {
8437 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068438 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468439 };
8440
8441 // Attempt to fetch the URL with a good cert
8442 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178443 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8444 "Host: www.example.org:443\r\n"
8445 "Proxy-Connection: keep-alive\r\n\r\n"),
8446 MockWrite("GET / HTTP/1.1\r\n"
8447 "Host: www.example.org\r\n"
8448 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468449 };
8450
8451 MockRead good_cert_reads[] = {
8452 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8453 MockRead("HTTP/1.0 200 OK\r\n"),
8454 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8455 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068456 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468457 };
8458
8459 StaticSocketDataProvider ssl_bad_certificate(
8460 bad_cert_reads, arraysize(bad_cert_reads),
8461 bad_cert_writes, arraysize(bad_cert_writes));
8462 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8463 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068464 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8465 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468466
8467 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8469 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8470 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468471
8472 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8474 session_deps_.socket_factory->AddSocketDataProvider(&data);
8475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468476
[email protected]49639fa2011-12-20 23:22:418477 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468478
danakj1fd259a02016-04-16 03:17:098479 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168480 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468481
tfarina42834112016-09-22 13:38:208482 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468484
8485 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018486 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468487
bnc691fda62016-08-12 00:43:168488 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468490
8491 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018492 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468493
bnc691fda62016-08-12 00:43:168494 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468495
wezca1070932016-05-26 20:30:528496 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468497 EXPECT_EQ(100, response->headers->GetContentLength());
8498}
8499
bncd16676a2016-07-20 16:23:018500TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428501 HttpRequestInfo request;
8502 request.method = "GET";
bncce36dca22015-04-21 22:11:238503 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438504 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8505 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428506
danakj1fd259a02016-04-16 03:17:098507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278509
[email protected]1c773ea12009-04-28 19:58:428510 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238511 MockWrite(
8512 "GET / HTTP/1.1\r\n"
8513 "Host: www.example.org\r\n"
8514 "Connection: keep-alive\r\n"
8515 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428516 };
8517
8518 // Lastly, the server responds with the actual content.
8519 MockRead data_reads[] = {
8520 MockRead("HTTP/1.0 200 OK\r\n"),
8521 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8522 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068523 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428524 };
8525
[email protected]31a2bfe2010-02-09 08:03:398526 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8527 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078528 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428529
[email protected]49639fa2011-12-20 23:22:418530 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428531
tfarina42834112016-09-22 13:38:208532 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428534
8535 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018536 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428537}
8538
bncd16676a2016-07-20 16:23:018539TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298540 HttpRequestInfo request;
8541 request.method = "GET";
bncce36dca22015-04-21 22:11:238542 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298543 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8544 "Chromium Ultra Awesome X Edition");
8545
rdsmith82957ad2015-09-16 19:42:038546 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278549
[email protected]da81f132010-08-18 23:39:298550 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178551 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8552 "Host: www.example.org:443\r\n"
8553 "Proxy-Connection: keep-alive\r\n"
8554 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298555 };
8556 MockRead data_reads[] = {
8557 // Return an error, so the transaction stops here (this test isn't
8558 // interested in the rest).
8559 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8560 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8561 MockRead("Proxy-Connection: close\r\n\r\n"),
8562 };
8563
8564 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8565 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078566 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298567
[email protected]49639fa2011-12-20 23:22:418568 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298569
tfarina42834112016-09-22 13:38:208570 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298572
8573 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018574 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298575}
8576
bncd16676a2016-07-20 16:23:018577TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428578 HttpRequestInfo request;
8579 request.method = "GET";
bncce36dca22015-04-21 22:11:238580 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168581 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8582 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428583
danakj1fd259a02016-04-16 03:17:098584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278586
[email protected]1c773ea12009-04-28 19:58:428587 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238588 MockWrite(
8589 "GET / HTTP/1.1\r\n"
8590 "Host: www.example.org\r\n"
8591 "Connection: keep-alive\r\n"
8592 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428593 };
8594
8595 // Lastly, the server responds with the actual content.
8596 MockRead data_reads[] = {
8597 MockRead("HTTP/1.0 200 OK\r\n"),
8598 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8599 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068600 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428601 };
8602
[email protected]31a2bfe2010-02-09 08:03:398603 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8604 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078605 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428606
[email protected]49639fa2011-12-20 23:22:418607 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428608
tfarina42834112016-09-22 13:38:208609 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428611
8612 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018613 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428614}
8615
bncd16676a2016-07-20 16:23:018616TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428617 HttpRequestInfo request;
8618 request.method = "POST";
bncce36dca22015-04-21 22:11:238619 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428620
danakj1fd259a02016-04-16 03:17:098621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168622 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278623
[email protected]1c773ea12009-04-28 19:58:428624 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238625 MockWrite(
8626 "POST / HTTP/1.1\r\n"
8627 "Host: www.example.org\r\n"
8628 "Connection: keep-alive\r\n"
8629 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428630 };
8631
8632 // Lastly, the server responds with the actual content.
8633 MockRead data_reads[] = {
8634 MockRead("HTTP/1.0 200 OK\r\n"),
8635 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8636 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068637 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428638 };
8639
[email protected]31a2bfe2010-02-09 08:03:398640 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8641 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078642 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428643
[email protected]49639fa2011-12-20 23:22:418644 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428645
tfarina42834112016-09-22 13:38:208646 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428648
8649 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018650 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428651}
8652
bncd16676a2016-07-20 16:23:018653TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428654 HttpRequestInfo request;
8655 request.method = "PUT";
bncce36dca22015-04-21 22:11:238656 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428657
danakj1fd259a02016-04-16 03:17:098658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168659 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278660
[email protected]1c773ea12009-04-28 19:58:428661 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238662 MockWrite(
8663 "PUT / HTTP/1.1\r\n"
8664 "Host: www.example.org\r\n"
8665 "Connection: keep-alive\r\n"
8666 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428667 };
8668
8669 // Lastly, the server responds with the actual content.
8670 MockRead data_reads[] = {
8671 MockRead("HTTP/1.0 200 OK\r\n"),
8672 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8673 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068674 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428675 };
8676
[email protected]31a2bfe2010-02-09 08:03:398677 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8678 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078679 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428680
[email protected]49639fa2011-12-20 23:22:418681 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428682
tfarina42834112016-09-22 13:38:208683 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018684 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428685
8686 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018687 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428688}
8689
bncd16676a2016-07-20 16:23:018690TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428691 HttpRequestInfo request;
8692 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238693 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428694
danakj1fd259a02016-04-16 03:17:098695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278697
[email protected]1c773ea12009-04-28 19:58:428698 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138699 MockWrite("HEAD / HTTP/1.1\r\n"
8700 "Host: www.example.org\r\n"
8701 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428702 };
8703
8704 // Lastly, the server responds with the actual content.
8705 MockRead data_reads[] = {
8706 MockRead("HTTP/1.0 200 OK\r\n"),
8707 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8708 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068709 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428710 };
8711
[email protected]31a2bfe2010-02-09 08:03:398712 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8713 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078714 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428715
[email protected]49639fa2011-12-20 23:22:418716 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428717
tfarina42834112016-09-22 13:38:208718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428720
8721 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018722 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428723}
8724
bncd16676a2016-07-20 16:23:018725TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428726 HttpRequestInfo request;
8727 request.method = "GET";
bncce36dca22015-04-21 22:11:238728 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428729 request.load_flags = LOAD_BYPASS_CACHE;
8730
danakj1fd259a02016-04-16 03:17:098731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278733
[email protected]1c773ea12009-04-28 19:58:428734 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238735 MockWrite(
8736 "GET / HTTP/1.1\r\n"
8737 "Host: www.example.org\r\n"
8738 "Connection: keep-alive\r\n"
8739 "Pragma: no-cache\r\n"
8740 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428741 };
8742
8743 // Lastly, the server responds with the actual content.
8744 MockRead data_reads[] = {
8745 MockRead("HTTP/1.0 200 OK\r\n"),
8746 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8747 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068748 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428749 };
8750
[email protected]31a2bfe2010-02-09 08:03:398751 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8752 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078753 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428754
[email protected]49639fa2011-12-20 23:22:418755 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428756
tfarina42834112016-09-22 13:38:208757 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018758 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428759
8760 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018761 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428762}
8763
bncd16676a2016-07-20 16:23:018764TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428765 HttpRequestInfo request;
8766 request.method = "GET";
bncce36dca22015-04-21 22:11:238767 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428768 request.load_flags = LOAD_VALIDATE_CACHE;
8769
danakj1fd259a02016-04-16 03:17:098770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278772
[email protected]1c773ea12009-04-28 19:58:428773 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238774 MockWrite(
8775 "GET / HTTP/1.1\r\n"
8776 "Host: www.example.org\r\n"
8777 "Connection: keep-alive\r\n"
8778 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428779 };
8780
8781 // Lastly, the server responds with the actual content.
8782 MockRead data_reads[] = {
8783 MockRead("HTTP/1.0 200 OK\r\n"),
8784 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8785 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068786 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428787 };
8788
[email protected]31a2bfe2010-02-09 08:03:398789 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8790 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078791 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428792
[email protected]49639fa2011-12-20 23:22:418793 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428794
tfarina42834112016-09-22 13:38:208795 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428797
8798 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018799 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428800}
8801
bncd16676a2016-07-20 16:23:018802TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428803 HttpRequestInfo request;
8804 request.method = "GET";
bncce36dca22015-04-21 22:11:238805 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438806 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428807
danakj1fd259a02016-04-16 03:17:098808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168809 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278810
[email protected]1c773ea12009-04-28 19:58:428811 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238812 MockWrite(
8813 "GET / HTTP/1.1\r\n"
8814 "Host: www.example.org\r\n"
8815 "Connection: keep-alive\r\n"
8816 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428817 };
8818
8819 // Lastly, the server responds with the actual content.
8820 MockRead data_reads[] = {
8821 MockRead("HTTP/1.0 200 OK\r\n"),
8822 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8823 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068824 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428825 };
8826
[email protected]31a2bfe2010-02-09 08:03:398827 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8828 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078829 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428830
[email protected]49639fa2011-12-20 23:22:418831 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428832
tfarina42834112016-09-22 13:38:208833 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428835
8836 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018837 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428838}
8839
bncd16676a2016-07-20 16:23:018840TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478841 HttpRequestInfo request;
8842 request.method = "GET";
bncce36dca22015-04-21 22:11:238843 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438844 request.extra_headers.SetHeader("referer", "www.foo.com");
8845 request.extra_headers.SetHeader("hEllo", "Kitty");
8846 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478847
danakj1fd259a02016-04-16 03:17:098848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168849 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278850
[email protected]270c6412010-03-29 22:02:478851 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238852 MockWrite(
8853 "GET / HTTP/1.1\r\n"
8854 "Host: www.example.org\r\n"
8855 "Connection: keep-alive\r\n"
8856 "referer: www.foo.com\r\n"
8857 "hEllo: Kitty\r\n"
8858 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478859 };
8860
8861 // Lastly, the server responds with the actual content.
8862 MockRead data_reads[] = {
8863 MockRead("HTTP/1.0 200 OK\r\n"),
8864 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8865 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068866 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478867 };
8868
8869 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8870 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478872
[email protected]49639fa2011-12-20 23:22:418873 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478874
tfarina42834112016-09-22 13:38:208875 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478877
8878 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018879 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478880}
8881
bncd16676a2016-07-20 16:23:018882TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278883 HttpRequestInfo request;
8884 request.method = "GET";
bncce36dca22015-04-21 22:11:238885 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278886
rdsmith82957ad2015-09-16 19:42:038887 session_deps_.proxy_service =
8888 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518889 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078890 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028891
danakj1fd259a02016-04-16 03:17:098892 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168893 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028894
[email protected]3cd17242009-06-23 02:59:028895 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8896 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8897
8898 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238899 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8900 MockWrite(
8901 "GET / HTTP/1.1\r\n"
8902 "Host: www.example.org\r\n"
8903 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028904
8905 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068906 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028907 MockRead("HTTP/1.0 200 OK\r\n"),
8908 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8909 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068910 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028911 };
8912
[email protected]31a2bfe2010-02-09 08:03:398913 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8914 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078915 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028916
[email protected]49639fa2011-12-20 23:22:418917 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028918
tfarina42834112016-09-22 13:38:208919 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028921
8922 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018923 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028924
bnc691fda62016-08-12 00:43:168925 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528926 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028927
tbansal2ecbbc72016-10-06 17:15:478928 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208929 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168930 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208931 TestLoadTimingNotReusedWithPac(load_timing_info,
8932 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8933
[email protected]3cd17242009-06-23 02:59:028934 std::string response_text;
bnc691fda62016-08-12 00:43:168935 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018936 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028937 EXPECT_EQ("Payload", response_text);
8938}
8939
bncd16676a2016-07-20 16:23:018940TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278941 HttpRequestInfo request;
8942 request.method = "GET";
bncce36dca22015-04-21 22:11:238943 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278944
rdsmith82957ad2015-09-16 19:42:038945 session_deps_.proxy_service =
8946 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518947 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078948 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028949
danakj1fd259a02016-04-16 03:17:098950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028952
[email protected]3cd17242009-06-23 02:59:028953 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8954 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8955
8956 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238957 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8958 arraysize(write_buffer)),
8959 MockWrite(
8960 "GET / HTTP/1.1\r\n"
8961 "Host: www.example.org\r\n"
8962 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028963
8964 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018965 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8966 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358967 MockRead("HTTP/1.0 200 OK\r\n"),
8968 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8969 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068970 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358971 };
8972
[email protected]31a2bfe2010-02-09 08:03:398973 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8974 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078975 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358976
[email protected]8ddf8322012-02-23 18:08:068977 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078978 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358979
[email protected]49639fa2011-12-20 23:22:418980 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358981
tfarina42834112016-09-22 13:38:208982 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358984
8985 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018986 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358987
[email protected]029c83b62013-01-24 05:28:208988 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168989 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208990 TestLoadTimingNotReusedWithPac(load_timing_info,
8991 CONNECT_TIMING_HAS_SSL_TIMES);
8992
bnc691fda62016-08-12 00:43:168993 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528994 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:478995 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:358996
8997 std::string response_text;
bnc691fda62016-08-12 00:43:168998 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018999 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359000 EXPECT_EQ("Payload", response_text);
9001}
9002
bncd16676a2016-07-20 16:23:019003TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209004 HttpRequestInfo request;
9005 request.method = "GET";
bncce36dca22015-04-21 22:11:239006 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209007
rdsmith82957ad2015-09-16 19:42:039008 session_deps_.proxy_service =
9009 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519010 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079011 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209012
danakj1fd259a02016-04-16 03:17:099013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209015
9016 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9017 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9018
9019 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239020 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9021 MockWrite(
9022 "GET / HTTP/1.1\r\n"
9023 "Host: www.example.org\r\n"
9024 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209025
9026 MockRead data_reads[] = {
9027 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9028 MockRead("HTTP/1.0 200 OK\r\n"),
9029 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9030 MockRead("Payload"),
9031 MockRead(SYNCHRONOUS, OK)
9032 };
9033
9034 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9035 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079036 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209037
9038 TestCompletionCallback callback;
9039
tfarina42834112016-09-22 13:38:209040 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019041 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209042
9043 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019044 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209045
bnc691fda62016-08-12 00:43:169046 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529047 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209048
9049 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169050 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209051 TestLoadTimingNotReused(load_timing_info,
9052 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9053
9054 std::string response_text;
bnc691fda62016-08-12 00:43:169055 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019056 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209057 EXPECT_EQ("Payload", response_text);
9058}
9059
bncd16676a2016-07-20 16:23:019060TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279061 HttpRequestInfo request;
9062 request.method = "GET";
bncce36dca22015-04-21 22:11:239063 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279064
rdsmith82957ad2015-09-16 19:42:039065 session_deps_.proxy_service =
9066 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519067 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079068 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359069
danakj1fd259a02016-04-16 03:17:099070 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359072
[email protected]e0c27be2009-07-15 13:09:359073 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9074 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379075 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239076 0x05, // Version
9077 0x01, // Command (CONNECT)
9078 0x00, // Reserved.
9079 0x03, // Address type (DOMAINNAME).
9080 0x0F, // Length of domain (15)
9081 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9082 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379083 };
[email protected]e0c27be2009-07-15 13:09:359084 const char kSOCKS5OkResponse[] =
9085 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9086
9087 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239088 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9089 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9090 MockWrite(
9091 "GET / HTTP/1.1\r\n"
9092 "Host: www.example.org\r\n"
9093 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359094
9095 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019096 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9097 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359098 MockRead("HTTP/1.0 200 OK\r\n"),
9099 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9100 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069101 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359102 };
9103
[email protected]31a2bfe2010-02-09 08:03:399104 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9105 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079106 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359107
[email protected]49639fa2011-12-20 23:22:419108 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359109
tfarina42834112016-09-22 13:38:209110 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359112
9113 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359115
bnc691fda62016-08-12 00:43:169116 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529117 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479118 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359119
[email protected]029c83b62013-01-24 05:28:209120 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169121 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209122 TestLoadTimingNotReusedWithPac(load_timing_info,
9123 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9124
[email protected]e0c27be2009-07-15 13:09:359125 std::string response_text;
bnc691fda62016-08-12 00:43:169126 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019127 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359128 EXPECT_EQ("Payload", response_text);
9129}
9130
bncd16676a2016-07-20 16:23:019131TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279132 HttpRequestInfo request;
9133 request.method = "GET";
bncce36dca22015-04-21 22:11:239134 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279135
rdsmith82957ad2015-09-16 19:42:039136 session_deps_.proxy_service =
9137 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519138 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079139 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359140
danakj1fd259a02016-04-16 03:17:099141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359143
[email protected]e0c27be2009-07-15 13:09:359144 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9145 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379146 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239147 0x05, // Version
9148 0x01, // Command (CONNECT)
9149 0x00, // Reserved.
9150 0x03, // Address type (DOMAINNAME).
9151 0x0F, // Length of domain (15)
9152 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9153 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379154 };
9155
[email protected]e0c27be2009-07-15 13:09:359156 const char kSOCKS5OkResponse[] =
9157 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9158
9159 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239160 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9161 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9162 arraysize(kSOCKS5OkRequest)),
9163 MockWrite(
9164 "GET / HTTP/1.1\r\n"
9165 "Host: www.example.org\r\n"
9166 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359167
9168 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019169 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9170 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029171 MockRead("HTTP/1.0 200 OK\r\n"),
9172 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9173 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069174 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029175 };
9176
[email protected]31a2bfe2010-02-09 08:03:399177 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9178 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079179 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029180
[email protected]8ddf8322012-02-23 18:08:069181 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029183
[email protected]49639fa2011-12-20 23:22:419184 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029185
tfarina42834112016-09-22 13:38:209186 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029188
9189 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019190 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029191
bnc691fda62016-08-12 00:43:169192 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529193 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479194 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029195
[email protected]029c83b62013-01-24 05:28:209196 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169197 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209198 TestLoadTimingNotReusedWithPac(load_timing_info,
9199 CONNECT_TIMING_HAS_SSL_TIMES);
9200
[email protected]3cd17242009-06-23 02:59:029201 std::string response_text;
bnc691fda62016-08-12 00:43:169202 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019203 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029204 EXPECT_EQ("Payload", response_text);
9205}
9206
[email protected]448d4ca52012-03-04 04:12:239207namespace {
9208
[email protected]04e5be32009-06-26 20:00:319209// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069210
9211struct GroupNameTest {
9212 std::string proxy_server;
9213 std::string url;
9214 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189215 bool ssl;
[email protected]2d731a32010-04-29 01:04:069216};
9217
danakj1fd259a02016-04-16 03:17:099218std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079219 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099220 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069221
bnc525e175a2016-06-20 12:36:409222 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539223 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219224 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129225 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229226 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429227 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469228 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069229
9230 return session;
9231}
9232
mmenkee65e7af2015-10-13 17:16:429233int GroupNameTransactionHelper(const std::string& url,
9234 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069235 HttpRequestInfo request;
9236 request.method = "GET";
9237 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069238
bnc691fda62016-08-12 00:43:169239 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279240
[email protected]49639fa2011-12-20 23:22:419241 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069242
9243 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209244 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069245}
9246
[email protected]448d4ca52012-03-04 04:12:239247} // namespace
9248
bncd16676a2016-07-20 16:23:019249TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069250 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239251 {
9252 "", // unused
9253 "http://www.example.org/direct",
9254 "www.example.org:80",
9255 false,
9256 },
9257 {
9258 "", // unused
9259 "http://[2001:1418:13:1::25]/direct",
9260 "[2001:1418:13:1::25]:80",
9261 false,
9262 },
[email protected]04e5be32009-06-26 20:00:319263
bncce36dca22015-04-21 22:11:239264 // SSL Tests
9265 {
9266 "", // unused
9267 "https://www.example.org/direct_ssl",
9268 "ssl/www.example.org:443",
9269 true,
9270 },
9271 {
9272 "", // unused
9273 "https://[2001:1418:13:1::25]/direct",
9274 "ssl/[2001:1418:13:1::25]:443",
9275 true,
9276 },
9277 {
9278 "", // unused
bncaa60ff402016-06-22 19:12:429279 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239280 "ssl/host.with.alternate:443",
9281 true,
9282 },
[email protected]2d731a32010-04-29 01:04:069283 };
[email protected]2ff8b312010-04-26 22:20:549284
viettrungluue4a8b882014-10-16 06:17:389285 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039286 session_deps_.proxy_service =
9287 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099288 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409289 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069290
mmenkee65e7af2015-10-13 17:16:429291 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289292 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589293 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139294 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589295 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
9296 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029297 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9298 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489299 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069300
9301 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429302 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189303 if (tests[i].ssl)
9304 EXPECT_EQ(tests[i].expected_group_name,
9305 ssl_conn_pool->last_group_name_received());
9306 else
9307 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289308 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069309 }
[email protected]2d731a32010-04-29 01:04:069310}
9311
bncd16676a2016-07-20 16:23:019312TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069313 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239314 {
9315 "http_proxy",
9316 "http://www.example.org/http_proxy_normal",
9317 "www.example.org:80",
9318 false,
9319 },
[email protected]2d731a32010-04-29 01:04:069320
bncce36dca22015-04-21 22:11:239321 // SSL Tests
9322 {
9323 "http_proxy",
9324 "https://www.example.org/http_connect_ssl",
9325 "ssl/www.example.org:443",
9326 true,
9327 },
[email protected]af3490e2010-10-16 21:02:299328
bncce36dca22015-04-21 22:11:239329 {
9330 "http_proxy",
bncaa60ff402016-06-22 19:12:429331 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239332 "ssl/host.with.alternate:443",
9333 true,
9334 },
[email protected]45499252013-01-23 17:12:569335
bncce36dca22015-04-21 22:11:239336 {
9337 "http_proxy",
9338 "ftp://ftp.google.com/http_proxy_normal",
9339 "ftp/ftp.google.com:21",
9340 false,
9341 },
[email protected]2d731a32010-04-29 01:04:069342 };
9343
viettrungluue4a8b882014-10-16 06:17:389344 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039345 session_deps_.proxy_service =
9346 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099347 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409348 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069349
mmenkee65e7af2015-10-13 17:16:429350 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069351
[email protected]e60e47a2010-07-14 03:37:189352 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139353 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349354 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139355 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349356 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589357 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399358 mock_pool_manager->SetSocketPoolForHTTPProxy(
9359 proxy_host, base::WrapUnique(http_proxy_pool));
9360 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9361 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489362 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069363
9364 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429365 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189366 if (tests[i].ssl)
9367 EXPECT_EQ(tests[i].expected_group_name,
9368 ssl_conn_pool->last_group_name_received());
9369 else
9370 EXPECT_EQ(tests[i].expected_group_name,
9371 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069372 }
[email protected]2d731a32010-04-29 01:04:069373}
9374
bncd16676a2016-07-20 16:23:019375TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069376 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239377 {
9378 "socks4://socks_proxy:1080",
9379 "http://www.example.org/socks4_direct",
9380 "socks4/www.example.org:80",
9381 false,
9382 },
9383 {
9384 "socks5://socks_proxy:1080",
9385 "http://www.example.org/socks5_direct",
9386 "socks5/www.example.org:80",
9387 false,
9388 },
[email protected]2d731a32010-04-29 01:04:069389
bncce36dca22015-04-21 22:11:239390 // SSL Tests
9391 {
9392 "socks4://socks_proxy:1080",
9393 "https://www.example.org/socks4_ssl",
9394 "socks4/ssl/www.example.org:443",
9395 true,
9396 },
9397 {
9398 "socks5://socks_proxy:1080",
9399 "https://www.example.org/socks5_ssl",
9400 "socks5/ssl/www.example.org:443",
9401 true,
9402 },
[email protected]af3490e2010-10-16 21:02:299403
bncce36dca22015-04-21 22:11:239404 {
9405 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429406 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239407 "socks4/ssl/host.with.alternate:443",
9408 true,
9409 },
[email protected]04e5be32009-06-26 20:00:319410 };
9411
viettrungluue4a8b882014-10-16 06:17:389412 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039413 session_deps_.proxy_service =
9414 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099415 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409416 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029417
mmenkee65e7af2015-10-13 17:16:429418 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319419
[email protected]e60e47a2010-07-14 03:37:189420 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139421 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349422 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139423 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349424 new CaptureGroupNameSSLSocketPool(NULL, NULL);
bnc87dcefc2017-05-25 12:47:589425 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399426 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9427 proxy_host, base::WrapUnique(socks_conn_pool));
9428 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9429 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489430 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319431
bnc691fda62016-08-12 00:43:169432 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319433
[email protected]2d731a32010-04-29 01:04:069434 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429435 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189436 if (tests[i].ssl)
9437 EXPECT_EQ(tests[i].expected_group_name,
9438 ssl_conn_pool->last_group_name_received());
9439 else
9440 EXPECT_EQ(tests[i].expected_group_name,
9441 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319442 }
9443}
9444
bncd16676a2016-07-20 16:23:019445TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279446 HttpRequestInfo request;
9447 request.method = "GET";
bncce36dca22015-04-21 22:11:239448 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279449
rdsmith82957ad2015-09-16 19:42:039450 session_deps_.proxy_service =
9451 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329452
[email protected]69719062010-01-05 20:09:219453 // This simulates failure resolving all hostnames; that means we will fail
9454 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079455 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329456
danakj1fd259a02016-04-16 03:17:099457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259459
[email protected]49639fa2011-12-20 23:22:419460 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259461
tfarina42834112016-09-22 13:38:209462 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259464
[email protected]9172a982009-06-06 00:30:259465 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019466 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259467}
9468
[email protected]685af592010-05-11 19:31:249469// Base test to make sure that when the load flags for a request specify to
9470// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029471void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079472 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279473 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109474 HttpRequestInfo request_info;
9475 request_info.method = "GET";
9476 request_info.load_flags = load_flags;
9477 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279478
[email protected]a2c2fb92009-07-18 07:31:049479 // Select a host resolver that does caching.
bnc87dcefc2017-05-25 12:47:589480 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329481
danakj1fd259a02016-04-16 03:17:099482 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289484
bncce36dca22015-04-21 22:11:239485 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289486 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299487 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109488 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079489 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239490 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109491 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209492 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479494 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019495 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289496
9497 // Verify that it was added to host cache, by doing a subsequent async lookup
9498 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109499 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079500 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239501 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109502 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209503 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019504 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289505
bncce36dca22015-04-21 22:11:239506 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289507 // we can tell if the next lookup hit the cache, or the "network".
9508 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239509 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289510
9511 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9512 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069513 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399514 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079515 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289516
[email protected]3b9cca42009-06-16 01:08:289517 // Run the request.
tfarina42834112016-09-22 13:38:209518 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019519 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419520 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289521
9522 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239523 // "www.example.org".
robpercival214763f2016-07-01 23:27:019524 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289525}
9526
[email protected]685af592010-05-11 19:31:249527// There are multiple load flags that should trigger the host cache bypass.
9528// Test each in isolation:
bncd16676a2016-07-20 16:23:019529TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249530 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9531}
9532
bncd16676a2016-07-20 16:23:019533TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249534 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9535}
9536
bncd16676a2016-07-20 16:23:019537TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249538 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9539}
9540
[email protected]0877e3d2009-10-17 22:29:579541// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019542TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579543 HttpRequestInfo request;
9544 request.method = "GET";
9545 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579546
9547 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069548 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579549 };
[email protected]31a2bfe2010-02-09 08:03:399550 StaticSocketDataProvider data(NULL, 0,
9551 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079552 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579554
[email protected]49639fa2011-12-20 23:22:419555 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579556
bnc691fda62016-08-12 00:43:169557 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579558
tfarina42834112016-09-22 13:38:209559 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019560 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579561
9562 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019563 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599564
9565 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169566 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599567 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579568}
9569
zmo9528c9f42015-08-04 22:12:089570// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019571TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579572 HttpRequestInfo request;
9573 request.method = "GET";
9574 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579575
9576 MockRead data_reads[] = {
9577 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069578 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579579 };
9580
[email protected]31a2bfe2010-02-09 08:03:399581 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079582 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579584
[email protected]49639fa2011-12-20 23:22:419585 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579586
bnc691fda62016-08-12 00:43:169587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579588
tfarina42834112016-09-22 13:38:209589 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579591
9592 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019593 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089594
bnc691fda62016-08-12 00:43:169595 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529596 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089597
wezca1070932016-05-26 20:30:529598 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089599 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9600
9601 std::string response_data;
bnc691fda62016-08-12 00:43:169602 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019603 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089604 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599605
9606 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169607 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599608 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579609}
9610
9611// Make sure that a dropped connection while draining the body for auth
9612// restart does the right thing.
bncd16676a2016-07-20 16:23:019613TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579614 HttpRequestInfo request;
9615 request.method = "GET";
bncce36dca22015-04-21 22:11:239616 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579617
9618 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239619 MockWrite(
9620 "GET / HTTP/1.1\r\n"
9621 "Host: www.example.org\r\n"
9622 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579623 };
9624
9625 MockRead data_reads1[] = {
9626 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9627 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9628 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9629 MockRead("Content-Length: 14\r\n\r\n"),
9630 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069631 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579632 };
9633
[email protected]31a2bfe2010-02-09 08:03:399634 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9635 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079636 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579637
bnc691fda62016-08-12 00:43:169638 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579639 // be issuing -- the final header line contains the credentials.
9640 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239641 MockWrite(
9642 "GET / HTTP/1.1\r\n"
9643 "Host: www.example.org\r\n"
9644 "Connection: keep-alive\r\n"
9645 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579646 };
9647
9648 // Lastly, the server responds with the actual content.
9649 MockRead data_reads2[] = {
9650 MockRead("HTTP/1.1 200 OK\r\n"),
9651 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9652 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069653 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579654 };
9655
[email protected]31a2bfe2010-02-09 08:03:399656 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9657 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079658 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579660
[email protected]49639fa2011-12-20 23:22:419661 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579662
bnc691fda62016-08-12 00:43:169663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509664
tfarina42834112016-09-22 13:38:209665 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579667
9668 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019669 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579670
bnc691fda62016-08-12 00:43:169671 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529672 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049673 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579674
[email protected]49639fa2011-12-20 23:22:419675 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579676
bnc691fda62016-08-12 00:43:169677 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579679
9680 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019681 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579682
bnc691fda62016-08-12 00:43:169683 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529684 ASSERT_TRUE(response);
9685 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579686 EXPECT_EQ(100, response->headers->GetContentLength());
9687}
9688
9689// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019690TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039691 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579692
9693 HttpRequestInfo request;
9694 request.method = "GET";
bncce36dca22015-04-21 22:11:239695 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579696
9697 MockRead proxy_reads[] = {
9698 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069699 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579700 };
9701
[email protected]31a2bfe2010-02-09 08:03:399702 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069703 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579704
[email protected]bb88e1d32013-05-03 23:11:079705 session_deps_.socket_factory->AddSocketDataProvider(&data);
9706 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579707
[email protected]49639fa2011-12-20 23:22:419708 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579709
[email protected]bb88e1d32013-05-03 23:11:079710 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579711
danakj1fd259a02016-04-16 03:17:099712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169713 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579714
tfarina42834112016-09-22 13:38:209715 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579717
9718 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019719 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579720}
9721
bncd16676a2016-07-20 16:23:019722TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469723 HttpRequestInfo request;
9724 request.method = "GET";
bncce36dca22015-04-21 22:11:239725 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469726
danakj1fd259a02016-04-16 03:17:099727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279729
[email protected]e22e1362009-11-23 21:31:129730 MockRead data_reads[] = {
9731 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069732 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129733 };
[email protected]9492e4a2010-02-24 00:58:469734
9735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079736 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469737
[email protected]49639fa2011-12-20 23:22:419738 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469739
tfarina42834112016-09-22 13:38:209740 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469742
robpercival214763f2016-07-01 23:27:019743 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469744
bnc691fda62016-08-12 00:43:169745 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529746 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469747
wezca1070932016-05-26 20:30:529748 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469749 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9750
9751 std::string response_data;
bnc691fda62016-08-12 00:43:169752 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019753 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129754}
9755
bncd16676a2016-07-20 16:23:019756TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159757 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529758 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149759 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219760 UploadFileElementReader::ScopedOverridingContentLengthForTests
9761 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339762
danakj1fd259a02016-04-16 03:17:099763 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079764 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149765 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079766 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229767 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279768
9769 HttpRequestInfo request;
9770 request.method = "POST";
bncce36dca22015-04-21 22:11:239771 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279772 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279773
danakj1fd259a02016-04-16 03:17:099774 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169775 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339776
9777 MockRead data_reads[] = {
9778 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9779 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069780 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339781 };
[email protected]31a2bfe2010-02-09 08:03:399782 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079783 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339784
[email protected]49639fa2011-12-20 23:22:419785 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339786
tfarina42834112016-09-22 13:38:209787 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019788 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339789
9790 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019791 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339792
bnc691fda62016-08-12 00:43:169793 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529794 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339795
maksim.sisove869bf52016-06-23 17:11:529796 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339797
[email protected]dd3aa792013-07-16 19:10:239798 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339799}
9800
bncd16676a2016-07-20 16:23:019801TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159802 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529803 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369804 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:489805 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
9806 base::WriteFile(temp_file, temp_file_content.c_str(),
9807 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119808 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369809
danakj1fd259a02016-04-16 03:17:099810 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079811 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149812 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079813 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229814 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279815
9816 HttpRequestInfo request;
9817 request.method = "POST";
bncce36dca22015-04-21 22:11:239818 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279819 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279820
[email protected]999dd8c2013-11-12 06:45:549821 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369824
[email protected]999dd8c2013-11-12 06:45:549825 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079826 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369827
[email protected]49639fa2011-12-20 23:22:419828 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369829
tfarina42834112016-09-22 13:38:209830 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369832
9833 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019834 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369835
[email protected]dd3aa792013-07-16 19:10:239836 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369837}
9838
bncd16676a2016-07-20 16:23:019839TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039840 class FakeUploadElementReader : public UploadElementReader {
9841 public:
9842 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209843 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039844
9845 const CompletionCallback& callback() const { return callback_; }
9846
9847 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209848 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039849 callback_ = callback;
9850 return ERR_IO_PENDING;
9851 }
avibf0746c2015-12-09 19:53:149852 uint64_t GetContentLength() const override { return 0; }
9853 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209854 int Read(IOBuffer* buf,
9855 int buf_length,
9856 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039857 return ERR_FAILED;
9858 }
9859
9860 private:
9861 CompletionCallback callback_;
9862 };
9863
9864 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099865 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9866 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229867 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039868
9869 HttpRequestInfo request;
9870 request.method = "POST";
bncce36dca22015-04-21 22:11:239871 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039872 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039873
danakj1fd259a02016-04-16 03:17:099874 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:589875 auto trans =
9876 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:039877
9878 StaticSocketDataProvider data;
9879 session_deps_.socket_factory->AddSocketDataProvider(&data);
9880
9881 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209882 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559884 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039885
9886 // Transaction is pending on request body initialization.
9887 ASSERT_FALSE(fake_reader->callback().is_null());
9888
9889 // Return Init()'s result after the transaction gets destroyed.
9890 trans.reset();
9891 fake_reader->callback().Run(OK); // Should not crash.
9892}
9893
[email protected]aeefc9e82010-02-19 16:18:279894// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019895TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279896 HttpRequestInfo request;
9897 request.method = "GET";
bncce36dca22015-04-21 22:11:239898 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279899
9900 // First transaction will request a resource and receive a Basic challenge
9901 // with realm="first_realm".
9902 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239903 MockWrite(
9904 "GET / HTTP/1.1\r\n"
9905 "Host: www.example.org\r\n"
9906 "Connection: keep-alive\r\n"
9907 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279908 };
9909 MockRead data_reads1[] = {
9910 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9911 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9912 "\r\n"),
9913 };
9914
bnc691fda62016-08-12 00:43:169915 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279916 // for first_realm. The server will reject and provide a challenge with
9917 // second_realm.
9918 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239919 MockWrite(
9920 "GET / HTTP/1.1\r\n"
9921 "Host: www.example.org\r\n"
9922 "Connection: keep-alive\r\n"
9923 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9924 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279925 };
9926 MockRead data_reads2[] = {
9927 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9928 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9929 "\r\n"),
9930 };
9931
9932 // This again fails, and goes back to first_realm. Make sure that the
9933 // entry is removed from cache.
9934 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239935 MockWrite(
9936 "GET / HTTP/1.1\r\n"
9937 "Host: www.example.org\r\n"
9938 "Connection: keep-alive\r\n"
9939 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9940 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279941 };
9942 MockRead data_reads3[] = {
9943 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9944 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9945 "\r\n"),
9946 };
9947
9948 // Try one last time (with the correct password) and get the resource.
9949 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239950 MockWrite(
9951 "GET / HTTP/1.1\r\n"
9952 "Host: www.example.org\r\n"
9953 "Connection: keep-alive\r\n"
9954 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9955 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279956 };
9957 MockRead data_reads4[] = {
9958 MockRead("HTTP/1.1 200 OK\r\n"
9959 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509960 "Content-Length: 5\r\n"
9961 "\r\n"
9962 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279963 };
9964
9965 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9966 data_writes1, arraysize(data_writes1));
9967 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9968 data_writes2, arraysize(data_writes2));
9969 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9970 data_writes3, arraysize(data_writes3));
9971 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9972 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079973 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9974 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9975 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9976 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279977
[email protected]49639fa2011-12-20 23:22:419978 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279979
danakj1fd259a02016-04-16 03:17:099980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509982
[email protected]aeefc9e82010-02-19 16:18:279983 // Issue the first request with Authorize headers. There should be a
9984 // password prompt for first_realm waiting to be filled in after the
9985 // transaction completes.
tfarina42834112016-09-22 13:38:209986 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019987 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279988 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019989 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169990 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529991 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049992 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529993 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049994 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439995 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049996 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199997 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279998
9999 // Issue the second request with an incorrect password. There should be a
10000 // password prompt for second_realm waiting to be filled in after the
10001 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110002 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610003 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10004 callback2.callback());
robpercival214763f2016-07-01 23:27:0110005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710006 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110007 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610008 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210009 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410010 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210011 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410012 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310013 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410014 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910015 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710016
10017 // Issue the third request with another incorrect password. There should be
10018 // a password prompt for first_realm waiting to be filled in. If the password
10019 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10020 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110021 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610022 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10023 callback3.callback());
robpercival214763f2016-07-01 23:27:0110024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710025 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110026 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610027 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210028 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410029 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210030 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410031 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310032 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410033 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910034 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710035
10036 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110037 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610038 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10039 callback4.callback());
robpercival214763f2016-07-01 23:27:0110040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710041 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110042 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610043 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210044 ASSERT_TRUE(response);
10045 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710046}
10047
bncd16676a2016-07-20 16:23:0110048TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210049 MockRead data_reads[] = {
10050 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310051 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210052 MockRead("\r\n"),
10053 MockRead("hello world"),
10054 MockRead(SYNCHRONOUS, OK),
10055 };
10056
10057 HttpRequestInfo request;
10058 request.method = "GET";
bncb26024382016-06-29 02:39:4510059 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210060
10061 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210062 session_deps_.socket_factory->AddSocketDataProvider(&data);
10063
bncb26024382016-06-29 02:39:4510064 SSLSocketDataProvider ssl(ASYNC, OK);
10065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10066
bncc958faa2015-07-31 18:14:5210067 TestCompletionCallback callback;
10068
danakj1fd259a02016-04-16 03:17:0910069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210071
tfarina42834112016-09-22 13:38:2010072 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210074
bncb26024382016-06-29 02:39:4510075 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010076 HttpServerProperties* http_server_properties =
10077 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410078 EXPECT_TRUE(
10079 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210080
robpercival214763f2016-07-01 23:27:0110081 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210082
bnc691fda62016-08-12 00:43:1610083 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210084 ASSERT_TRUE(response);
10085 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210086 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10087 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210088 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210089
10090 std::string response_data;
bnc691fda62016-08-12 00:43:1610091 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210092 EXPECT_EQ("hello world", response_data);
10093
zhongyic4de03032017-05-19 04:07:3410094 AlternativeServiceInfoVector alternative_service_info_vector =
10095 http_server_properties->GetAlternativeServiceInfos(test_server);
10096 ASSERT_EQ(1u, alternative_service_info_vector.size());
10097 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10098 EXPECT_EQ(alternative_service,
10099 alternative_service_info_vector[0].alternative_service);
bncc958faa2015-07-31 18:14:5210100}
10101
bnce3dd56f2016-06-01 10:37:1110102// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110103TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110104 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110105 MockRead data_reads[] = {
10106 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310107 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110108 MockRead("\r\n"),
10109 MockRead("hello world"),
10110 MockRead(SYNCHRONOUS, OK),
10111 };
10112
10113 HttpRequestInfo request;
10114 request.method = "GET";
10115 request.url = GURL("http://www.example.org/");
10116 request.load_flags = 0;
10117
10118 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10119 session_deps_.socket_factory->AddSocketDataProvider(&data);
10120
10121 TestCompletionCallback callback;
10122
10123 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610124 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110125
10126 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010127 HttpServerProperties* http_server_properties =
10128 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410129 EXPECT_TRUE(
10130 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110131
tfarina42834112016-09-22 13:38:2010132 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110133 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10134 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110135
bnc691fda62016-08-12 00:43:1610136 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110137 ASSERT_TRUE(response);
10138 ASSERT_TRUE(response->headers);
10139 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10140 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210141 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110142
10143 std::string response_data;
bnc691fda62016-08-12 00:43:1610144 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110145 EXPECT_EQ("hello world", response_data);
10146
zhongyic4de03032017-05-19 04:07:3410147 EXPECT_TRUE(
10148 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110149}
10150
bnca86731e2017-04-17 12:31:2810151// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510152// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110153TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510154 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810155 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510156
bnc8bef8da22016-05-30 01:28:2510157 HttpRequestInfo request;
10158 request.method = "GET";
bncb26024382016-06-29 02:39:4510159 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510160 request.load_flags = 0;
10161
10162 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10163 StaticSocketDataProvider first_data;
10164 first_data.set_connect_data(mock_connect);
10165 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510166 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610167 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510168 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510169
10170 MockRead data_reads[] = {
10171 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10172 MockRead(ASYNC, OK),
10173 };
10174 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10175 0);
10176 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10177
10178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10179
bnc525e175a2016-06-20 12:36:4010180 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510181 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110182 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10183 444);
bnc8bef8da22016-05-30 01:28:2510184 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10185 http_server_properties->SetAlternativeService(
10186 url::SchemeHostPort(request.url), alternative_service, expiration);
10187
bnc691fda62016-08-12 00:43:1610188 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510189 TestCompletionCallback callback;
10190
tfarina42834112016-09-22 13:38:2010191 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510192 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110193 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510194}
10195
bnce3dd56f2016-06-01 10:37:1110196// Regression test for https://crbug.com/615497:
10197// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110198TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110199 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110200 HttpRequestInfo request;
10201 request.method = "GET";
10202 request.url = GURL("http://www.example.org/");
10203 request.load_flags = 0;
10204
10205 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10206 StaticSocketDataProvider first_data;
10207 first_data.set_connect_data(mock_connect);
10208 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10209
10210 MockRead data_reads[] = {
10211 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10212 MockRead(ASYNC, OK),
10213 };
10214 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10215 0);
10216 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10217
10218 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10219
bnc525e175a2016-06-20 12:36:4010220 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110221 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110222 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110223 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10224 http_server_properties->SetAlternativeService(
10225 url::SchemeHostPort(request.url), alternative_service, expiration);
10226
bnc691fda62016-08-12 00:43:1610227 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110228 TestCompletionCallback callback;
10229
tfarina42834112016-09-22 13:38:2010230 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110231 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110232 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110233}
10234
bncd16676a2016-07-20 16:23:0110235TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810236 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010238 HttpServerProperties* http_server_properties =
10239 session->http_server_properties();
bncb26024382016-06-29 02:39:4510240 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110241 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810242 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010243 http_server_properties->SetAlternativeService(
10244 test_server, alternative_service, expiration);
zhongyic4de03032017-05-19 04:07:3410245 EXPECT_EQ(
10246 1u,
10247 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810248
10249 // Send a clear header.
10250 MockRead data_reads[] = {
10251 MockRead("HTTP/1.1 200 OK\r\n"),
10252 MockRead("Alt-Svc: clear\r\n"),
10253 MockRead("\r\n"),
10254 MockRead("hello world"),
10255 MockRead(SYNCHRONOUS, OK),
10256 };
10257 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10258 session_deps_.socket_factory->AddSocketDataProvider(&data);
10259
bncb26024382016-06-29 02:39:4510260 SSLSocketDataProvider ssl(ASYNC, OK);
10261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10262
bnc4f575852015-10-14 18:35:0810263 HttpRequestInfo request;
10264 request.method = "GET";
bncb26024382016-06-29 02:39:4510265 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810266
10267 TestCompletionCallback callback;
10268
bnc691fda62016-08-12 00:43:1610269 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810270
tfarina42834112016-09-22 13:38:2010271 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110272 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810273
bnc691fda62016-08-12 00:43:1610274 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210275 ASSERT_TRUE(response);
10276 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810277 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10278 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210279 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810280
10281 std::string response_data;
bnc691fda62016-08-12 00:43:1610282 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810283 EXPECT_EQ("hello world", response_data);
10284
zhongyic4de03032017-05-19 04:07:3410285 EXPECT_TRUE(
10286 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810287}
10288
bncd16676a2016-07-20 16:23:0110289TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210290 MockRead data_reads[] = {
10291 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310292 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10293 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210294 MockRead("hello world"),
10295 MockRead(SYNCHRONOUS, OK),
10296 };
10297
10298 HttpRequestInfo request;
10299 request.method = "GET";
bncb26024382016-06-29 02:39:4510300 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210301
10302 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210303 session_deps_.socket_factory->AddSocketDataProvider(&data);
10304
bncb26024382016-06-29 02:39:4510305 SSLSocketDataProvider ssl(ASYNC, OK);
10306 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10307
bncc958faa2015-07-31 18:14:5210308 TestCompletionCallback callback;
10309
danakj1fd259a02016-04-16 03:17:0910310 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610311 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210312
tfarina42834112016-09-22 13:38:2010313 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110314 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210315
bncb26024382016-06-29 02:39:4510316 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010317 HttpServerProperties* http_server_properties =
10318 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410319 EXPECT_TRUE(
10320 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210321
robpercival214763f2016-07-01 23:27:0110322 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210323
bnc691fda62016-08-12 00:43:1610324 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210325 ASSERT_TRUE(response);
10326 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210327 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10328 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210329 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210330
10331 std::string response_data;
bnc691fda62016-08-12 00:43:1610332 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210333 EXPECT_EQ("hello world", response_data);
10334
zhongyic4de03032017-05-19 04:07:3410335 AlternativeServiceInfoVector alternative_service_info_vector =
10336 http_server_properties->GetAlternativeServiceInfos(test_server);
10337 ASSERT_EQ(2u, alternative_service_info_vector.size());
10338
10339 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
10340 EXPECT_EQ(alternative_service,
10341 alternative_service_info_vector[0].alternative_service);
10342 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10343 1234);
10344 EXPECT_EQ(alternative_service_2,
10345 alternative_service_info_vector[1].alternative_service);
bncc958faa2015-07-31 18:14:5210346}
10347
bncd16676a2016-07-20 16:23:0110348TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610349 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210350 HostPortPair alternative("alternative.example.org", 443);
10351 std::string origin_url = "https://origin.example.org:443";
10352 std::string alternative_url = "https://alternative.example.org:443";
10353
10354 // Negotiate HTTP/1.1 with alternative.example.org.
10355 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610356 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10358
10359 // HTTP/1.1 data for request.
10360 MockWrite http_writes[] = {
10361 MockWrite("GET / HTTP/1.1\r\n"
10362 "Host: alternative.example.org\r\n"
10363 "Connection: keep-alive\r\n\r\n"),
10364 };
10365
10366 MockRead http_reads[] = {
10367 MockRead("HTTP/1.1 200 OK\r\n"
10368 "Content-Type: text/html; charset=iso-8859-1\r\n"
10369 "Content-Length: 40\r\n\r\n"
10370 "first HTTP/1.1 response from alternative"),
10371 };
10372 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10373 http_writes, arraysize(http_writes));
10374 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10375
10376 StaticSocketDataProvider data_refused;
10377 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10378 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10379
zhongyi3d4a55e72016-04-22 20:36:4610380 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910381 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010382 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210383 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110384 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210385 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610386 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010387 expiration);
zhongyi48704c182015-12-07 07:52:0210388 // Mark the QUIC alternative service as broken.
10389 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10390
zhongyi48704c182015-12-07 07:52:0210391 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610392 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210393 request.method = "GET";
10394 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210395 TestCompletionCallback callback;
10396 NetErrorDetails details;
10397 EXPECT_FALSE(details.quic_broken);
10398
tfarina42834112016-09-22 13:38:2010399 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610400 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210401 EXPECT_TRUE(details.quic_broken);
10402}
10403
bncd16676a2016-07-20 16:23:0110404TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610405 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210406 HostPortPair alternative1("alternative1.example.org", 443);
10407 HostPortPair alternative2("alternative2.example.org", 443);
10408 std::string origin_url = "https://origin.example.org:443";
10409 std::string alternative_url1 = "https://alternative1.example.org:443";
10410 std::string alternative_url2 = "https://alternative2.example.org:443";
10411
10412 // Negotiate HTTP/1.1 with alternative1.example.org.
10413 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610414 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10416
10417 // HTTP/1.1 data for request.
10418 MockWrite http_writes[] = {
10419 MockWrite("GET / HTTP/1.1\r\n"
10420 "Host: alternative1.example.org\r\n"
10421 "Connection: keep-alive\r\n\r\n"),
10422 };
10423
10424 MockRead http_reads[] = {
10425 MockRead("HTTP/1.1 200 OK\r\n"
10426 "Content-Type: text/html; charset=iso-8859-1\r\n"
10427 "Content-Length: 40\r\n\r\n"
10428 "first HTTP/1.1 response from alternative1"),
10429 };
10430 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10431 http_writes, arraysize(http_writes));
10432 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10433
10434 StaticSocketDataProvider data_refused;
10435 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10436 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10437
danakj1fd259a02016-04-16 03:17:0910438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010439 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210440 session->http_server_properties();
10441
zhongyi3d4a55e72016-04-22 20:36:4610442 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210443 AlternativeServiceInfoVector alternative_service_info_vector;
10444 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10445
bnc3472afd2016-11-17 15:27:2110446 AlternativeService alternative_service1(kProtoQUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010447 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210448 expiration);
10449 alternative_service_info_vector.push_back(alternative_service_info1);
bnc3472afd2016-11-17 15:27:2110450 AlternativeService alternative_service2(kProtoQUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010451 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210452 expiration);
10453 alternative_service_info_vector.push_back(alternative_service_info2);
10454
10455 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610456 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210457
10458 // Mark one of the QUIC alternative service as broken.
10459 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410460 EXPECT_EQ(2u,
10461 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210462
zhongyi48704c182015-12-07 07:52:0210463 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210465 request.method = "GET";
10466 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210467 TestCompletionCallback callback;
10468 NetErrorDetails details;
10469 EXPECT_FALSE(details.quic_broken);
10470
tfarina42834112016-09-22 13:38:2010471 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610472 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210473 EXPECT_FALSE(details.quic_broken);
10474}
10475
bncd16676a2016-07-20 16:23:0110476TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210477 HttpRequestInfo request;
10478 request.method = "GET";
bncb26024382016-06-29 02:39:4510479 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210480
[email protected]d973e99a2012-02-17 21:02:3610481 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210482 StaticSocketDataProvider first_data;
10483 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710484 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510485 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610486 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210488
10489 MockRead data_reads[] = {
10490 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10491 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610492 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210493 };
10494 StaticSocketDataProvider second_data(
10495 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710496 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210497
danakj1fd259a02016-04-16 03:17:0910498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210499
bnc525e175a2016-06-20 12:36:4010500 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310501 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610502 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110503 // Port must be < 1024, or the header will be ignored (since initial port was
10504 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010505 const AlternativeService alternative_service(
bnc3472afd2016-11-17 15:27:2110506 kProtoHTTP2, "www.example.org",
bncd9b132e2015-07-08 05:16:1010507 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210508 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610509 http_server_properties->SetAlternativeService(server, alternative_service,
10510 expiration);
[email protected]564b4912010-03-09 16:30:4210511
bnc691fda62016-08-12 00:43:1610512 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110513 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210514
tfarina42834112016-09-22 13:38:2010515 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10517 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210518
bnc691fda62016-08-12 00:43:1610519 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210520 ASSERT_TRUE(response);
10521 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210522 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10523
10524 std::string response_data;
bnc691fda62016-08-12 00:43:1610525 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210526 EXPECT_EQ("hello world", response_data);
10527
zhongyic4de03032017-05-19 04:07:3410528 const AlternativeServiceInfoVector alternative_service_info_vector =
10529 http_server_properties->GetAlternativeServiceInfos(server);
10530 ASSERT_EQ(1u, alternative_service_info_vector.size());
10531 EXPECT_EQ(alternative_service,
10532 alternative_service_info_vector[0].alternative_service);
10533 EXPECT_TRUE(
10534 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210535}
10536
bnc55ff9da2015-08-19 18:42:3510537// Ensure that we are not allowed to redirect traffic via an alternate protocol
10538// to an unrestricted (port >= 1024) when the original traffic was on a
10539// restricted port (port < 1024). Ensure that we can redirect in all other
10540// cases.
bncd16676a2016-07-20 16:23:0110541TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110542 HttpRequestInfo restricted_port_request;
10543 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510544 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110545 restricted_port_request.load_flags = 0;
10546
[email protected]d973e99a2012-02-17 21:02:3610547 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110548 StaticSocketDataProvider first_data;
10549 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710550 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110551
10552 MockRead data_reads[] = {
10553 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10554 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610555 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110556 };
10557 StaticSocketDataProvider second_data(
10558 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710559 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510560 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610561 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110563
danakj1fd259a02016-04-16 03:17:0910564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110565
bnc525e175a2016-06-20 12:36:4010566 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310567 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110568 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110569 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10570 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210571 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210572 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610573 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010574 expiration);
[email protected]3912662a32011-10-04 00:51:1110575
bnc691fda62016-08-12 00:43:1610576 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110577 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110578
tfarina42834112016-09-22 13:38:2010579 int rv = trans.Start(&restricted_port_request, callback.callback(),
10580 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110582 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110583 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910584}
[email protected]3912662a32011-10-04 00:51:1110585
bnc55ff9da2015-08-19 18:42:3510586// Ensure that we are allowed to redirect traffic via an alternate protocol to
10587// an unrestricted (port >= 1024) when the original traffic was on a restricted
10588// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110589TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710590 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910591
10592 HttpRequestInfo restricted_port_request;
10593 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510594 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910595 restricted_port_request.load_flags = 0;
10596
10597 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10598 StaticSocketDataProvider first_data;
10599 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710600 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910601
10602 MockRead data_reads[] = {
10603 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10604 MockRead("hello world"),
10605 MockRead(ASYNC, OK),
10606 };
10607 StaticSocketDataProvider second_data(
10608 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710609 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510610 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610611 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910613
danakj1fd259a02016-04-16 03:17:0910614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910615
bnc525e175a2016-06-20 12:36:4010616 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910617 session->http_server_properties();
10618 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110619 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10620 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210621 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210622 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610623 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010624 expiration);
[email protected]c54c6962013-02-01 04:53:1910625
bnc691fda62016-08-12 00:43:1610626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910627 TestCompletionCallback callback;
10628
tfarina42834112016-09-22 13:38:2010629 EXPECT_EQ(ERR_IO_PENDING,
10630 trans.Start(&restricted_port_request, callback.callback(),
10631 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910632 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110633 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110634}
10635
bnc55ff9da2015-08-19 18:42:3510636// Ensure that we are not allowed to redirect traffic via an alternate protocol
10637// to an unrestricted (port >= 1024) when the original traffic was on a
10638// restricted port (port < 1024). Ensure that we can redirect in all other
10639// cases.
bncd16676a2016-07-20 16:23:0110640TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110641 HttpRequestInfo restricted_port_request;
10642 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510643 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110644 restricted_port_request.load_flags = 0;
10645
[email protected]d973e99a2012-02-17 21:02:3610646 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110647 StaticSocketDataProvider first_data;
10648 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710649 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110650
10651 MockRead data_reads[] = {
10652 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10653 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610654 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110655 };
10656 StaticSocketDataProvider second_data(
10657 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710658 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110659
bncb26024382016-06-29 02:39:4510660 SSLSocketDataProvider ssl(ASYNC, OK);
10661 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10662
danakj1fd259a02016-04-16 03:17:0910663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110664
bnc525e175a2016-06-20 12:36:4010665 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310666 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110667 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110668 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10669 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210670 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210671 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610672 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010673 expiration);
[email protected]3912662a32011-10-04 00:51:1110674
bnc691fda62016-08-12 00:43:1610675 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110676 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110677
tfarina42834112016-09-22 13:38:2010678 int rv = trans.Start(&restricted_port_request, callback.callback(),
10679 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110681 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110682 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110683}
10684
bnc55ff9da2015-08-19 18:42:3510685// Ensure that we are not allowed to redirect traffic via an alternate protocol
10686// to an unrestricted (port >= 1024) when the original traffic was on a
10687// restricted port (port < 1024). Ensure that we can redirect in all other
10688// cases.
bncd16676a2016-07-20 16:23:0110689TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110690 HttpRequestInfo unrestricted_port_request;
10691 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510692 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110693 unrestricted_port_request.load_flags = 0;
10694
[email protected]d973e99a2012-02-17 21:02:3610695 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110696 StaticSocketDataProvider first_data;
10697 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710698 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110699
10700 MockRead data_reads[] = {
10701 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10702 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610703 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110704 };
10705 StaticSocketDataProvider second_data(
10706 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710707 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510708 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610709 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510710 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110711
danakj1fd259a02016-04-16 03:17:0910712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110713
bnc525e175a2016-06-20 12:36:4010714 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310715 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110716 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110717 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10718 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210719 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210720 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610721 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010722 expiration);
[email protected]3912662a32011-10-04 00:51:1110723
bnc691fda62016-08-12 00:43:1610724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110725 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110726
bnc691fda62016-08-12 00:43:1610727 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010728 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110730 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110731 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110732}
10733
bnc55ff9da2015-08-19 18:42:3510734// Ensure that we are not allowed to redirect traffic via an alternate protocol
10735// to an unrestricted (port >= 1024) when the original traffic was on a
10736// restricted port (port < 1024). Ensure that we can redirect in all other
10737// cases.
bncd16676a2016-07-20 16:23:0110738TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110739 HttpRequestInfo unrestricted_port_request;
10740 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510741 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110742 unrestricted_port_request.load_flags = 0;
10743
[email protected]d973e99a2012-02-17 21:02:3610744 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110745 StaticSocketDataProvider first_data;
10746 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710747 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110748
10749 MockRead data_reads[] = {
10750 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10751 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610752 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110753 };
10754 StaticSocketDataProvider second_data(
10755 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710756 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110757
bncb26024382016-06-29 02:39:4510758 SSLSocketDataProvider ssl(ASYNC, OK);
10759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10760
danakj1fd259a02016-04-16 03:17:0910761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110762
bnc525e175a2016-06-20 12:36:4010763 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310764 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210765 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110766 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10767 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210768 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210769 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610770 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010771 expiration);
[email protected]3912662a32011-10-04 00:51:1110772
bnc691fda62016-08-12 00:43:1610773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110774 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110775
bnc691fda62016-08-12 00:43:1610776 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010777 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110779 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110780 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110781}
10782
bnc55ff9da2015-08-19 18:42:3510783// Ensure that we are not allowed to redirect traffic via an alternate protocol
10784// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10785// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110786TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210787 HttpRequestInfo request;
10788 request.method = "GET";
bncce36dca22015-04-21 22:11:2310789 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210790
10791 // The alternate protocol request will error out before we attempt to connect,
10792 // so only the standard HTTP request will try to connect.
10793 MockRead data_reads[] = {
10794 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10795 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610796 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210797 };
10798 StaticSocketDataProvider data(
10799 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710800 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210801
danakj1fd259a02016-04-16 03:17:0910802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210803
bnc525e175a2016-06-20 12:36:4010804 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210805 session->http_server_properties();
10806 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110807 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10808 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210809 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210810 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610811 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210812
bnc691fda62016-08-12 00:43:1610813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210814 TestCompletionCallback callback;
10815
tfarina42834112016-09-22 13:38:2010816 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210818 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110819 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210820
bnc691fda62016-08-12 00:43:1610821 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210822 ASSERT_TRUE(response);
10823 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210824 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10825
10826 std::string response_data;
bnc691fda62016-08-12 00:43:1610827 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210828 EXPECT_EQ("hello world", response_data);
10829}
10830
bncd16676a2016-07-20 16:23:0110831TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410832 HttpRequestInfo request;
10833 request.method = "GET";
bncb26024382016-06-29 02:39:4510834 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410835
10836 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210837 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310838 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210839 MockRead("\r\n"),
10840 MockRead("hello world"),
10841 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10842 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410843
10844 StaticSocketDataProvider first_transaction(
10845 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710846 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510847 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610848 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410850
bnc032658ba2016-09-26 18:17:1510851 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410852
bncdf80d44fd2016-07-15 20:27:4110853 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510854 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110855 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410856
bnc42331402016-07-25 13:36:1510857 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110858 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410859 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110860 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410861 };
10862
rch8e6c6c42015-05-01 14:05:1310863 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10864 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710865 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410866
[email protected]d973e99a2012-02-17 21:02:3610867 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510868 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10869 NULL, 0, NULL, 0);
10870 hanging_non_alternate_protocol_socket.set_connect_data(
10871 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710872 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510873 &hanging_non_alternate_protocol_socket);
10874
[email protected]49639fa2011-12-20 23:22:4110875 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410876
danakj1fd259a02016-04-16 03:17:0910877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810878 auto trans =
10879 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410880
tfarina42834112016-09-22 13:38:2010881 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10883 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410884
10885 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210886 ASSERT_TRUE(response);
10887 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410888 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10889
10890 std::string response_data;
robpercival214763f2016-07-01 23:27:0110891 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410892 EXPECT_EQ("hello world", response_data);
10893
bnc87dcefc2017-05-25 12:47:5810894 trans =
10895 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5410896
tfarina42834112016-09-22 13:38:2010897 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10899 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410900
10901 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210902 ASSERT_TRUE(response);
10903 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210904 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310905 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210906 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410907
robpercival214763f2016-07-01 23:27:0110908 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410909 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410910}
10911
bncd16676a2016-07-20 16:23:0110912TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510913 HttpRequestInfo request;
10914 request.method = "GET";
bncb26024382016-06-29 02:39:4510915 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510916
bncb26024382016-06-29 02:39:4510917 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510918 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210919 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310920 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210921 MockRead("\r\n"),
10922 MockRead("hello world"),
10923 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10924 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510925 };
10926
bncb26024382016-06-29 02:39:4510927 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10928 0);
10929 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510930
bncb26024382016-06-29 02:39:4510931 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10932 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10933
10934 // Second transaction starts an alternative and a non-alternative Job.
10935 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610936 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810937 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10938 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810939 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10940
10941 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10942 hanging_socket2.set_connect_data(never_finishing_connect);
10943 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510944
bncb26024382016-06-29 02:39:4510945 // Third transaction starts an alternative and a non-alternative job.
10946 // The non-alternative job hangs, but the alternative one succeeds.
10947 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110948 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510949 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110950 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510951 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510952 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110953 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510954 };
bnc42331402016-07-25 13:36:1510955 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110956 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510957 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110958 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510959 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110960 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10961 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310962 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510963 };
10964
rch8e6c6c42015-05-01 14:05:1310965 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10966 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710967 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510968
bnc032658ba2016-09-26 18:17:1510969 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510970
mmenkecc2298e2015-12-07 18:20:1810971 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10972 hanging_socket3.set_connect_data(never_finishing_connect);
10973 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510974
danakj1fd259a02016-04-16 03:17:0910975 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110976 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010977 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510978
tfarina42834112016-09-22 13:38:2010979 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10981 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510982
10983 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210984 ASSERT_TRUE(response);
10985 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510986 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10987
10988 std::string response_data;
robpercival214763f2016-07-01 23:27:0110989 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5510990 EXPECT_EQ("hello world", response_data);
10991
[email protected]49639fa2011-12-20 23:22:4110992 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010993 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2010994 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5510996
[email protected]49639fa2011-12-20 23:22:4110997 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5010998 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2010999 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511001
robpercival214763f2016-07-01 23:27:0111002 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11003 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511004
11005 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211006 ASSERT_TRUE(response);
11007 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211008 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511009 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211010 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111011 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511012 EXPECT_EQ("hello!", response_data);
11013
11014 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211015 ASSERT_TRUE(response);
11016 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211017 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511018 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211019 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111020 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511021 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511022}
11023
bncd16676a2016-07-20 16:23:0111024TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511025 HttpRequestInfo request;
11026 request.method = "GET";
bncb26024382016-06-29 02:39:4511027 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511028
11029 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211030 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311031 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211032 MockRead("\r\n"),
11033 MockRead("hello world"),
11034 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11035 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511036 };
11037
11038 StaticSocketDataProvider first_transaction(
11039 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711040 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511041
[email protected]8ddf8322012-02-23 18:08:0611042 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711043 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511044
[email protected]d973e99a2012-02-17 21:02:3611045 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511046 StaticSocketDataProvider hanging_alternate_protocol_socket(
11047 NULL, 0, NULL, 0);
11048 hanging_alternate_protocol_socket.set_connect_data(
11049 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711050 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511051 &hanging_alternate_protocol_socket);
11052
bncb26024382016-06-29 02:39:4511053 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811054 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11055 NULL, 0);
11056 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511058
[email protected]49639fa2011-12-20 23:22:4111059 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511060
danakj1fd259a02016-04-16 03:17:0911061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811062 auto trans =
11063 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511064
tfarina42834112016-09-22 13:38:2011065 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11067 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511068
11069 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211070 ASSERT_TRUE(response);
11071 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511072 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11073
11074 std::string response_data;
robpercival214763f2016-07-01 23:27:0111075 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511076 EXPECT_EQ("hello world", response_data);
11077
bnc87dcefc2017-05-25 12:47:5811078 trans =
11079 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511080
tfarina42834112016-09-22 13:38:2011081 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111082 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11083 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511084
11085 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211086 ASSERT_TRUE(response);
11087 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511088 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11089 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211090 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511091
robpercival214763f2016-07-01 23:27:0111092 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511093 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511094}
11095
[email protected]631f1322010-04-30 17:59:1111096class CapturingProxyResolver : public ProxyResolver {
11097 public:
sammce90c9212015-05-27 23:43:3511098 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011099 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111100
dchengb03027d2014-10-21 12:00:2011101 int GetProxyForURL(const GURL& url,
11102 ProxyInfo* results,
11103 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511104 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011105 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011106 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11107 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211108 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111109 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211110 return OK;
[email protected]631f1322010-04-30 17:59:1111111 }
11112
[email protected]24476402010-07-20 20:55:1711113 const std::vector<GURL>& resolved() const { return resolved_; }
11114
11115 private:
[email protected]631f1322010-04-30 17:59:1111116 std::vector<GURL> resolved_;
11117
11118 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11119};
11120
sammce64b2362015-04-29 03:50:2311121class CapturingProxyResolverFactory : public ProxyResolverFactory {
11122 public:
11123 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11124 : ProxyResolverFactory(false), resolver_(resolver) {}
11125
11126 int CreateProxyResolver(
11127 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911128 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311129 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911130 std::unique_ptr<Request>* request) override {
bnc87dcefc2017-05-25 12:47:5811131 *resolver = base::MakeUnique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311132 return OK;
11133 }
11134
11135 private:
11136 ProxyResolver* resolver_;
11137};
11138
bnc2e884782016-08-11 19:45:1911139// Test that proxy is resolved using the origin url,
11140// regardless of the alternative server.
11141TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11142 // Configure proxy to bypass www.example.org, which is the origin URL.
11143 ProxyConfig proxy_config;
11144 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11145 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11146 auto proxy_config_service =
11147 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11148
11149 CapturingProxyResolver capturing_proxy_resolver;
11150 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11151 &capturing_proxy_resolver);
11152
11153 TestNetLog net_log;
11154
11155 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11156 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11157 &net_log);
11158
11159 session_deps_.net_log = &net_log;
11160
11161 // Configure alternative service with a hostname that is not bypassed by the
11162 // proxy.
11163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11164 HttpServerProperties* http_server_properties =
11165 session->http_server_properties();
11166 url::SchemeHostPort server("https", "www.example.org", 443);
11167 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111168 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911169 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11170 http_server_properties->SetAlternativeService(server, alternative_service,
11171 expiration);
11172
11173 // Non-alternative job should hang.
11174 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11175 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11176 nullptr, 0);
11177 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11178 session_deps_.socket_factory->AddSocketDataProvider(
11179 &hanging_alternate_protocol_socket);
11180
bnc032658ba2016-09-26 18:17:1511181 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911182
11183 HttpRequestInfo request;
11184 request.method = "GET";
11185 request.url = GURL("https://www.example.org/");
11186 request.load_flags = 0;
11187
11188 SpdySerializedFrame req(
11189 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11190
11191 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11192
11193 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11194 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11195 MockRead spdy_reads[] = {
11196 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11197 };
11198
11199 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11200 arraysize(spdy_writes));
11201 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11202
11203 TestCompletionCallback callback;
11204
11205 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11206
tfarina42834112016-09-22 13:38:2011207 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911208 EXPECT_THAT(callback.GetResult(rv), IsOk());
11209
11210 const HttpResponseInfo* response = trans.GetResponseInfo();
11211 ASSERT_TRUE(response);
11212 ASSERT_TRUE(response->headers);
11213 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11214 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211215 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911216
11217 std::string response_data;
11218 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11219 EXPECT_EQ("hello!", response_data);
11220
11221 // Origin host bypasses proxy, no resolution should have happened.
11222 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11223}
11224
bncd16676a2016-07-20 16:23:0111225TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111226 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211227 proxy_config.set_auto_detect(true);
11228 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111229
sammc5dd160c2015-04-02 02:43:1311230 CapturingProxyResolver capturing_proxy_resolver;
bnc87dcefc2017-05-25 12:47:5811231 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11232 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11233 base::MakeUnique<CapturingProxyResolverFactory>(
11234 &capturing_proxy_resolver),
11235 nullptr);
vishal.b62985ca92015-04-17 08:45:5111236 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711237 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111238
11239 HttpRequestInfo request;
11240 request.method = "GET";
bncb26024382016-06-29 02:39:4511241 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111242
11243 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211244 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311245 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211246 MockRead("\r\n"),
11247 MockRead("hello world"),
11248 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11249 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111250 };
11251
11252 StaticSocketDataProvider first_transaction(
11253 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711254 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511255 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611256 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111258
bnc032658ba2016-09-26 18:17:1511259 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111260
bncdf80d44fd2016-07-15 20:27:4111261 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511262 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111263 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311264 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511265 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11266 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311267 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111268 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111269 };
11270
[email protected]d911f1b2010-05-05 22:39:4211271 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11272
bnc42331402016-07-25 13:36:1511273 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111274 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111275 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111276 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11277 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111278 };
11279
rch8e6c6c42015-05-01 14:05:1311280 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11281 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711282 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111283
[email protected]d973e99a2012-02-17 21:02:3611284 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511285 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11286 NULL, 0, NULL, 0);
11287 hanging_non_alternate_protocol_socket.set_connect_data(
11288 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711289 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511290 &hanging_non_alternate_protocol_socket);
11291
[email protected]49639fa2011-12-20 23:22:4111292 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111293
danakj1fd259a02016-04-16 03:17:0911294 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811295 auto trans =
11296 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111297
tfarina42834112016-09-22 13:38:2011298 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111299 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11300 EXPECT_THAT(callback.WaitForResult(), IsOk());
11301
11302 const HttpResponseInfo* response = trans->GetResponseInfo();
11303 ASSERT_TRUE(response);
11304 ASSERT_TRUE(response->headers);
11305 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11306 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211307 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111308
11309 std::string response_data;
11310 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11311 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111312
bnc87dcefc2017-05-25 12:47:5811313 trans =
11314 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111315
tfarina42834112016-09-22 13:38:2011316 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111317 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11318 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111319
mmenkea2dcd3bf2016-08-16 21:49:4111320 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211321 ASSERT_TRUE(response);
11322 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211323 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311324 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211325 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111326
robpercival214763f2016-07-01 23:27:0111327 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111328 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511329 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11330 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311331 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311332 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311333 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111334
[email protected]029c83b62013-01-24 05:28:2011335 LoadTimingInfo load_timing_info;
11336 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11337 TestLoadTimingNotReusedWithPac(load_timing_info,
11338 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111339}
[email protected]631f1322010-04-30 17:59:1111340
bncd16676a2016-07-20 16:23:0111341TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811342 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411343 HttpRequestInfo request;
11344 request.method = "GET";
bncb26024382016-06-29 02:39:4511345 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411346
11347 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211348 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311349 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211350 MockRead("\r\n"),
11351 MockRead("hello world"),
11352 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411353 };
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]2ff8b312010-04-26 22:20:5411361
bnc032658ba2016-09-26 18:17:1511362 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411363
bncdf80d44fd2016-07-15 20:27:4111364 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511365 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111366 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411367
bnc42331402016-07-25 13:36:1511368 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111369 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411370 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111371 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411372 };
11373
rch8e6c6c42015-05-01 14:05:1311374 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11375 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711376 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411377
[email protected]83039bb2011-12-09 18:43:5511378 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411379
danakj1fd259a02016-04-16 03:17:0911380 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411381
bnc87dcefc2017-05-25 12:47:5811382 auto trans =
11383 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411384
tfarina42834112016-09-22 13:38:2011385 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111386 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11387 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411388
11389 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211390 ASSERT_TRUE(response);
11391 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411392 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11393
11394 std::string response_data;
robpercival214763f2016-07-01 23:27:0111395 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411396 EXPECT_EQ("hello world", response_data);
11397
11398 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511399 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011400 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311401 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711402 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011403 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811404
bnc87dcefc2017-05-25 12:47:5811405 trans =
11406 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411407
tfarina42834112016-09-22 13:38:2011408 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11410 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411411
11412 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211413 ASSERT_TRUE(response);
11414 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211415 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311416 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211417 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411418
robpercival214763f2016-07-01 23:27:0111419 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411420 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211421}
11422
[email protected]044de0642010-06-17 10:42:1511423// GenerateAuthToken is a mighty big test.
11424// It tests all permutation of GenerateAuthToken behavior:
11425// - Synchronous and Asynchronous completion.
11426// - OK or error on completion.
11427// - Direct connection, non-authenticating proxy, and authenticating proxy.
11428// - HTTP or HTTPS backend (to include proxy tunneling).
11429// - Non-authenticating and authenticating backend.
11430//
[email protected]fe3b7dc2012-02-03 19:52:0911431// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511432// problems generating an auth token for an authenticating proxy, we don't
11433// need to test all permutations of the backend server).
11434//
11435// The test proceeds by going over each of the configuration cases, and
11436// potentially running up to three rounds in each of the tests. The TestConfig
11437// specifies both the configuration for the test as well as the expectations
11438// for the results.
bncd16676a2016-07-20 16:23:0111439TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011440 static const char kServer[] = "http://www.example.com";
11441 static const char kSecureServer[] = "https://www.example.com";
11442 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511443
11444 enum AuthTiming {
11445 AUTH_NONE,
11446 AUTH_SYNC,
11447 AUTH_ASYNC,
11448 };
11449
11450 const MockWrite kGet(
11451 "GET / HTTP/1.1\r\n"
11452 "Host: www.example.com\r\n"
11453 "Connection: keep-alive\r\n\r\n");
11454 const MockWrite kGetProxy(
11455 "GET http://www.example.com/ HTTP/1.1\r\n"
11456 "Host: www.example.com\r\n"
11457 "Proxy-Connection: keep-alive\r\n\r\n");
11458 const MockWrite kGetAuth(
11459 "GET / HTTP/1.1\r\n"
11460 "Host: www.example.com\r\n"
11461 "Connection: keep-alive\r\n"
11462 "Authorization: auth_token\r\n\r\n");
11463 const MockWrite kGetProxyAuth(
11464 "GET http://www.example.com/ HTTP/1.1\r\n"
11465 "Host: www.example.com\r\n"
11466 "Proxy-Connection: keep-alive\r\n"
11467 "Proxy-Authorization: auth_token\r\n\r\n");
11468 const MockWrite kGetAuthThroughProxy(
11469 "GET http://www.example.com/ HTTP/1.1\r\n"
11470 "Host: www.example.com\r\n"
11471 "Proxy-Connection: keep-alive\r\n"
11472 "Authorization: auth_token\r\n\r\n");
11473 const MockWrite kGetAuthWithProxyAuth(
11474 "GET http://www.example.com/ HTTP/1.1\r\n"
11475 "Host: www.example.com\r\n"
11476 "Proxy-Connection: keep-alive\r\n"
11477 "Proxy-Authorization: auth_token\r\n"
11478 "Authorization: auth_token\r\n\r\n");
11479 const MockWrite kConnect(
11480 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711481 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511482 "Proxy-Connection: keep-alive\r\n\r\n");
11483 const MockWrite kConnectProxyAuth(
11484 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711485 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511486 "Proxy-Connection: keep-alive\r\n"
11487 "Proxy-Authorization: auth_token\r\n\r\n");
11488
11489 const MockRead kSuccess(
11490 "HTTP/1.1 200 OK\r\n"
11491 "Content-Type: text/html; charset=iso-8859-1\r\n"
11492 "Content-Length: 3\r\n\r\n"
11493 "Yes");
11494 const MockRead kFailure(
11495 "Should not be called.");
11496 const MockRead kServerChallenge(
11497 "HTTP/1.1 401 Unauthorized\r\n"
11498 "WWW-Authenticate: Mock realm=server\r\n"
11499 "Content-Type: text/html; charset=iso-8859-1\r\n"
11500 "Content-Length: 14\r\n\r\n"
11501 "Unauthorized\r\n");
11502 const MockRead kProxyChallenge(
11503 "HTTP/1.1 407 Unauthorized\r\n"
11504 "Proxy-Authenticate: Mock realm=proxy\r\n"
11505 "Proxy-Connection: close\r\n"
11506 "Content-Type: text/html; charset=iso-8859-1\r\n"
11507 "Content-Length: 14\r\n\r\n"
11508 "Unauthorized\r\n");
11509 const MockRead kProxyConnected(
11510 "HTTP/1.1 200 Connection Established\r\n\r\n");
11511
11512 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11513 // no constructors, but the C++ compiler on Windows warns about
11514 // unspecified data in compound literals. So, moved to using constructors,
11515 // and TestRound's created with the default constructor should not be used.
11516 struct TestRound {
11517 TestRound()
11518 : expected_rv(ERR_UNEXPECTED),
11519 extra_write(NULL),
11520 extra_read(NULL) {
11521 }
11522 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11523 int expected_rv_arg)
11524 : write(write_arg),
11525 read(read_arg),
11526 expected_rv(expected_rv_arg),
11527 extra_write(NULL),
11528 extra_read(NULL) {
11529 }
11530 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11531 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111532 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511533 : write(write_arg),
11534 read(read_arg),
11535 expected_rv(expected_rv_arg),
11536 extra_write(extra_write_arg),
11537 extra_read(extra_read_arg) {
11538 }
11539 MockWrite write;
11540 MockRead read;
11541 int expected_rv;
11542 const MockWrite* extra_write;
11543 const MockRead* extra_read;
11544 };
11545
11546 static const int kNoSSL = 500;
11547
11548 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111549 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111550 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511551 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111552 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111553 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511554 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111555 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511556 int num_auth_rounds;
11557 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611558 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511559 } test_configs[] = {
asankac93076192016-10-03 15:46:0211560 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111561 {__LINE__,
11562 nullptr,
asankac93076192016-10-03 15:46:0211563 AUTH_NONE,
11564 OK,
11565 kServer,
11566 AUTH_NONE,
11567 OK,
11568 1,
11569 kNoSSL,
11570 {TestRound(kGet, kSuccess, OK)}},
11571 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111572 {__LINE__,
11573 nullptr,
asankac93076192016-10-03 15:46:0211574 AUTH_NONE,
11575 OK,
11576 kServer,
11577 AUTH_SYNC,
11578 OK,
11579 2,
11580 kNoSSL,
11581 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511582 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111583 {__LINE__,
11584 nullptr,
asankac93076192016-10-03 15:46:0211585 AUTH_NONE,
11586 OK,
11587 kServer,
11588 AUTH_SYNC,
11589 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611590 3,
11591 kNoSSL,
11592 {TestRound(kGet, kServerChallenge, OK),
11593 TestRound(kGet, kServerChallenge, OK),
11594 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111595 {__LINE__,
11596 nullptr,
asankae2257db2016-10-11 22:03:1611597 AUTH_NONE,
11598 OK,
11599 kServer,
11600 AUTH_SYNC,
11601 ERR_UNSUPPORTED_AUTH_SCHEME,
11602 2,
11603 kNoSSL,
11604 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111605 {__LINE__,
11606 nullptr,
asankae2257db2016-10-11 22:03:1611607 AUTH_NONE,
11608 OK,
11609 kServer,
11610 AUTH_SYNC,
11611 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11612 2,
11613 kNoSSL,
11614 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111615 {__LINE__,
11616 kProxy,
asankae2257db2016-10-11 22:03:1611617 AUTH_SYNC,
11618 ERR_FAILED,
11619 kServer,
11620 AUTH_NONE,
11621 OK,
11622 2,
11623 kNoSSL,
11624 {TestRound(kGetProxy, kProxyChallenge, OK),
11625 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111626 {__LINE__,
11627 kProxy,
asankae2257db2016-10-11 22:03:1611628 AUTH_ASYNC,
11629 ERR_FAILED,
11630 kServer,
11631 AUTH_NONE,
11632 OK,
11633 2,
11634 kNoSSL,
11635 {TestRound(kGetProxy, kProxyChallenge, OK),
11636 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111637 {__LINE__,
11638 nullptr,
asankae2257db2016-10-11 22:03:1611639 AUTH_NONE,
11640 OK,
11641 kServer,
11642 AUTH_SYNC,
11643 ERR_FAILED,
asankac93076192016-10-03 15:46:0211644 2,
11645 kNoSSL,
11646 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611647 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111648 {__LINE__,
11649 nullptr,
asankae2257db2016-10-11 22:03:1611650 AUTH_NONE,
11651 OK,
11652 kServer,
11653 AUTH_ASYNC,
11654 ERR_FAILED,
11655 2,
11656 kNoSSL,
11657 {TestRound(kGet, kServerChallenge, OK),
11658 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111659 {__LINE__,
11660 nullptr,
asankac93076192016-10-03 15:46:0211661 AUTH_NONE,
11662 OK,
11663 kServer,
11664 AUTH_ASYNC,
11665 OK,
11666 2,
11667 kNoSSL,
11668 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511669 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111670 {__LINE__,
11671 nullptr,
asankac93076192016-10-03 15:46:0211672 AUTH_NONE,
11673 OK,
11674 kServer,
11675 AUTH_ASYNC,
11676 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611677 3,
asankac93076192016-10-03 15:46:0211678 kNoSSL,
11679 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611680 // The second round uses a HttpAuthHandlerMock that always succeeds.
11681 TestRound(kGet, kServerChallenge, OK),
11682 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211683 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111684 {__LINE__,
11685 kProxy,
asankac93076192016-10-03 15:46:0211686 AUTH_NONE,
11687 OK,
11688 kServer,
11689 AUTH_NONE,
11690 OK,
11691 1,
11692 kNoSSL,
11693 {TestRound(kGetProxy, kSuccess, OK)}},
11694 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111695 {__LINE__,
11696 kProxy,
asankac93076192016-10-03 15:46:0211697 AUTH_NONE,
11698 OK,
11699 kServer,
11700 AUTH_SYNC,
11701 OK,
11702 2,
11703 kNoSSL,
11704 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511705 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111706 {__LINE__,
11707 kProxy,
asankac93076192016-10-03 15:46:0211708 AUTH_NONE,
11709 OK,
11710 kServer,
11711 AUTH_SYNC,
11712 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611713 3,
asankac93076192016-10-03 15:46:0211714 kNoSSL,
11715 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611716 TestRound(kGetProxy, kServerChallenge, OK),
11717 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111718 {__LINE__,
11719 kProxy,
asankac93076192016-10-03 15:46:0211720 AUTH_NONE,
11721 OK,
11722 kServer,
11723 AUTH_ASYNC,
11724 OK,
11725 2,
11726 kNoSSL,
11727 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511728 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111729 {__LINE__,
11730 kProxy,
asankac93076192016-10-03 15:46:0211731 AUTH_NONE,
11732 OK,
11733 kServer,
11734 AUTH_ASYNC,
11735 ERR_INVALID_AUTH_CREDENTIALS,
11736 2,
11737 kNoSSL,
11738 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611739 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211740 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111741 {__LINE__,
11742 kProxy,
asankac93076192016-10-03 15:46:0211743 AUTH_SYNC,
11744 OK,
11745 kServer,
11746 AUTH_NONE,
11747 OK,
11748 2,
11749 kNoSSL,
11750 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511751 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111752 {__LINE__,
11753 kProxy,
asankac93076192016-10-03 15:46:0211754 AUTH_SYNC,
11755 ERR_INVALID_AUTH_CREDENTIALS,
11756 kServer,
11757 AUTH_NONE,
11758 OK,
11759 2,
11760 kNoSSL,
11761 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611762 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111763 {__LINE__,
11764 kProxy,
asankac93076192016-10-03 15:46:0211765 AUTH_ASYNC,
11766 OK,
11767 kServer,
11768 AUTH_NONE,
11769 OK,
11770 2,
11771 kNoSSL,
11772 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511773 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111774 {__LINE__,
11775 kProxy,
asankac93076192016-10-03 15:46:0211776 AUTH_ASYNC,
11777 ERR_INVALID_AUTH_CREDENTIALS,
11778 kServer,
11779 AUTH_NONE,
11780 OK,
11781 2,
11782 kNoSSL,
11783 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611784 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111785 {__LINE__,
11786 kProxy,
11787 AUTH_ASYNC,
11788 ERR_INVALID_AUTH_CREDENTIALS,
11789 kServer,
11790 AUTH_NONE,
11791 OK,
11792 3,
11793 kNoSSL,
11794 {TestRound(kGetProxy, kProxyChallenge, OK),
11795 TestRound(kGetProxy, kProxyChallenge, OK),
11796 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211797 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111798 {__LINE__,
11799 kProxy,
asankac93076192016-10-03 15:46:0211800 AUTH_SYNC,
11801 OK,
11802 kServer,
11803 AUTH_SYNC,
11804 OK,
11805 3,
11806 kNoSSL,
11807 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511808 TestRound(kGetProxyAuth, kServerChallenge, OK),
11809 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111810 {__LINE__,
11811 kProxy,
asankac93076192016-10-03 15:46:0211812 AUTH_SYNC,
11813 OK,
11814 kServer,
11815 AUTH_SYNC,
11816 ERR_INVALID_AUTH_CREDENTIALS,
11817 3,
11818 kNoSSL,
11819 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511820 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611821 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111822 {__LINE__,
11823 kProxy,
asankac93076192016-10-03 15:46:0211824 AUTH_ASYNC,
11825 OK,
11826 kServer,
11827 AUTH_SYNC,
11828 OK,
11829 3,
11830 kNoSSL,
11831 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511832 TestRound(kGetProxyAuth, kServerChallenge, OK),
11833 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111834 {__LINE__,
11835 kProxy,
asankac93076192016-10-03 15:46:0211836 AUTH_ASYNC,
11837 OK,
11838 kServer,
11839 AUTH_SYNC,
11840 ERR_INVALID_AUTH_CREDENTIALS,
11841 3,
11842 kNoSSL,
11843 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511844 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611845 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111846 {__LINE__,
11847 kProxy,
asankac93076192016-10-03 15:46:0211848 AUTH_SYNC,
11849 OK,
11850 kServer,
11851 AUTH_ASYNC,
11852 OK,
11853 3,
11854 kNoSSL,
11855 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511856 TestRound(kGetProxyAuth, kServerChallenge, OK),
11857 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111858 {__LINE__,
11859 kProxy,
11860 AUTH_SYNC,
11861 ERR_INVALID_AUTH_CREDENTIALS,
11862 kServer,
11863 AUTH_ASYNC,
11864 OK,
11865 4,
11866 kNoSSL,
11867 {TestRound(kGetProxy, kProxyChallenge, OK),
11868 TestRound(kGetProxy, kProxyChallenge, OK),
11869 TestRound(kGetProxyAuth, kServerChallenge, OK),
11870 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11871 {__LINE__,
11872 kProxy,
asankac93076192016-10-03 15:46:0211873 AUTH_SYNC,
11874 OK,
11875 kServer,
11876 AUTH_ASYNC,
11877 ERR_INVALID_AUTH_CREDENTIALS,
11878 3,
11879 kNoSSL,
11880 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511881 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611882 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111883 {__LINE__,
11884 kProxy,
asankac93076192016-10-03 15:46:0211885 AUTH_ASYNC,
11886 OK,
11887 kServer,
11888 AUTH_ASYNC,
11889 OK,
11890 3,
11891 kNoSSL,
11892 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511893 TestRound(kGetProxyAuth, kServerChallenge, OK),
11894 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111895 {__LINE__,
11896 kProxy,
asankac93076192016-10-03 15:46:0211897 AUTH_ASYNC,
11898 OK,
11899 kServer,
11900 AUTH_ASYNC,
11901 ERR_INVALID_AUTH_CREDENTIALS,
11902 3,
11903 kNoSSL,
11904 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511905 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611906 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111907 {__LINE__,
11908 kProxy,
11909 AUTH_ASYNC,
11910 ERR_INVALID_AUTH_CREDENTIALS,
11911 kServer,
11912 AUTH_ASYNC,
11913 ERR_INVALID_AUTH_CREDENTIALS,
11914 4,
11915 kNoSSL,
11916 {TestRound(kGetProxy, kProxyChallenge, OK),
11917 TestRound(kGetProxy, kProxyChallenge, OK),
11918 TestRound(kGetProxyAuth, kServerChallenge, OK),
11919 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211920 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111921 {__LINE__,
11922 nullptr,
asankac93076192016-10-03 15:46:0211923 AUTH_NONE,
11924 OK,
11925 kSecureServer,
11926 AUTH_NONE,
11927 OK,
11928 1,
11929 0,
11930 {TestRound(kGet, kSuccess, OK)}},
11931 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111932 {__LINE__,
11933 nullptr,
asankac93076192016-10-03 15:46:0211934 AUTH_NONE,
11935 OK,
11936 kSecureServer,
11937 AUTH_SYNC,
11938 OK,
11939 2,
11940 0,
11941 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511942 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111943 {__LINE__,
11944 nullptr,
asankac93076192016-10-03 15:46:0211945 AUTH_NONE,
11946 OK,
11947 kSecureServer,
11948 AUTH_SYNC,
11949 ERR_INVALID_AUTH_CREDENTIALS,
11950 2,
11951 0,
asankae2257db2016-10-11 22:03:1611952 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111953 {__LINE__,
11954 nullptr,
asankac93076192016-10-03 15:46:0211955 AUTH_NONE,
11956 OK,
11957 kSecureServer,
11958 AUTH_ASYNC,
11959 OK,
11960 2,
11961 0,
11962 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511963 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111964 {__LINE__,
11965 nullptr,
asankac93076192016-10-03 15:46:0211966 AUTH_NONE,
11967 OK,
11968 kSecureServer,
11969 AUTH_ASYNC,
11970 ERR_INVALID_AUTH_CREDENTIALS,
11971 2,
11972 0,
asankae2257db2016-10-11 22:03:1611973 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211974 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111975 {__LINE__,
11976 kProxy,
asankac93076192016-10-03 15:46:0211977 AUTH_NONE,
11978 OK,
11979 kSecureServer,
11980 AUTH_NONE,
11981 OK,
11982 1,
11983 0,
11984 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11985 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111986 {__LINE__,
11987 kProxy,
asankac93076192016-10-03 15:46:0211988 AUTH_NONE,
11989 OK,
11990 kSecureServer,
11991 AUTH_SYNC,
11992 OK,
11993 2,
11994 0,
11995 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1511996 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111997 {__LINE__,
11998 kProxy,
asankac93076192016-10-03 15:46:0211999 AUTH_NONE,
12000 OK,
12001 kSecureServer,
12002 AUTH_SYNC,
12003 ERR_INVALID_AUTH_CREDENTIALS,
12004 2,
12005 0,
12006 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612007 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112008 {__LINE__,
12009 kProxy,
asankac93076192016-10-03 15:46:0212010 AUTH_NONE,
12011 OK,
12012 kSecureServer,
12013 AUTH_ASYNC,
12014 OK,
12015 2,
12016 0,
12017 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512018 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112019 {__LINE__,
12020 kProxy,
asankac93076192016-10-03 15:46:0212021 AUTH_NONE,
12022 OK,
12023 kSecureServer,
12024 AUTH_ASYNC,
12025 ERR_INVALID_AUTH_CREDENTIALS,
12026 2,
12027 0,
12028 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612029 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212030 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112031 {__LINE__,
12032 kProxy,
asankac93076192016-10-03 15:46:0212033 AUTH_SYNC,
12034 OK,
12035 kSecureServer,
12036 AUTH_NONE,
12037 OK,
12038 2,
12039 1,
12040 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512041 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112042 {__LINE__,
12043 kProxy,
asankac93076192016-10-03 15:46:0212044 AUTH_SYNC,
12045 ERR_INVALID_AUTH_CREDENTIALS,
12046 kSecureServer,
12047 AUTH_NONE,
12048 OK,
12049 2,
12050 kNoSSL,
12051 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612052 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112053 {__LINE__,
12054 kProxy,
asankae2257db2016-10-11 22:03:1612055 AUTH_SYNC,
12056 ERR_UNSUPPORTED_AUTH_SCHEME,
12057 kSecureServer,
12058 AUTH_NONE,
12059 OK,
12060 2,
12061 kNoSSL,
12062 {TestRound(kConnect, kProxyChallenge, OK),
12063 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112064 {__LINE__,
12065 kProxy,
asankae2257db2016-10-11 22:03:1612066 AUTH_SYNC,
12067 ERR_UNEXPECTED,
12068 kSecureServer,
12069 AUTH_NONE,
12070 OK,
12071 2,
12072 kNoSSL,
12073 {TestRound(kConnect, kProxyChallenge, OK),
12074 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112075 {__LINE__,
12076 kProxy,
asankac93076192016-10-03 15:46:0212077 AUTH_ASYNC,
12078 OK,
12079 kSecureServer,
12080 AUTH_NONE,
12081 OK,
12082 2,
12083 1,
12084 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512085 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112086 {__LINE__,
12087 kProxy,
asankac93076192016-10-03 15:46:0212088 AUTH_ASYNC,
12089 ERR_INVALID_AUTH_CREDENTIALS,
12090 kSecureServer,
12091 AUTH_NONE,
12092 OK,
12093 2,
12094 kNoSSL,
12095 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612096 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212097 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112098 {__LINE__,
12099 kProxy,
asankac93076192016-10-03 15:46:0212100 AUTH_SYNC,
12101 OK,
12102 kSecureServer,
12103 AUTH_SYNC,
12104 OK,
12105 3,
12106 1,
12107 {TestRound(kConnect, kProxyChallenge, OK),
12108 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12109 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512110 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112111 {__LINE__,
12112 kProxy,
asankac93076192016-10-03 15:46:0212113 AUTH_SYNC,
12114 OK,
12115 kSecureServer,
12116 AUTH_SYNC,
12117 ERR_INVALID_AUTH_CREDENTIALS,
12118 3,
12119 1,
12120 {TestRound(kConnect, kProxyChallenge, OK),
12121 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12122 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612123 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112124 {__LINE__,
12125 kProxy,
asankac93076192016-10-03 15:46:0212126 AUTH_ASYNC,
12127 OK,
12128 kSecureServer,
12129 AUTH_SYNC,
12130 OK,
12131 3,
12132 1,
12133 {TestRound(kConnect, kProxyChallenge, OK),
12134 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12135 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512136 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112137 {__LINE__,
12138 kProxy,
asankac93076192016-10-03 15:46:0212139 AUTH_ASYNC,
12140 OK,
12141 kSecureServer,
12142 AUTH_SYNC,
12143 ERR_INVALID_AUTH_CREDENTIALS,
12144 3,
12145 1,
12146 {TestRound(kConnect, kProxyChallenge, OK),
12147 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12148 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612149 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112150 {__LINE__,
12151 kProxy,
asankac93076192016-10-03 15:46:0212152 AUTH_SYNC,
12153 OK,
12154 kSecureServer,
12155 AUTH_ASYNC,
12156 OK,
12157 3,
12158 1,
12159 {TestRound(kConnect, kProxyChallenge, OK),
12160 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12161 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512162 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112163 {__LINE__,
12164 kProxy,
asankac93076192016-10-03 15:46:0212165 AUTH_SYNC,
12166 OK,
12167 kSecureServer,
12168 AUTH_ASYNC,
12169 ERR_INVALID_AUTH_CREDENTIALS,
12170 3,
12171 1,
12172 {TestRound(kConnect, kProxyChallenge, OK),
12173 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12174 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612175 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112176 {__LINE__,
12177 kProxy,
asankac93076192016-10-03 15:46:0212178 AUTH_ASYNC,
12179 OK,
12180 kSecureServer,
12181 AUTH_ASYNC,
12182 OK,
12183 3,
12184 1,
12185 {TestRound(kConnect, kProxyChallenge, OK),
12186 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12187 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512188 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112189 {__LINE__,
12190 kProxy,
asankac93076192016-10-03 15:46:0212191 AUTH_ASYNC,
12192 OK,
12193 kSecureServer,
12194 AUTH_ASYNC,
12195 ERR_INVALID_AUTH_CREDENTIALS,
12196 3,
12197 1,
12198 {TestRound(kConnect, kProxyChallenge, OK),
12199 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12200 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612201 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112202 {__LINE__,
12203 kProxy,
12204 AUTH_ASYNC,
12205 ERR_INVALID_AUTH_CREDENTIALS,
12206 kSecureServer,
12207 AUTH_ASYNC,
12208 ERR_INVALID_AUTH_CREDENTIALS,
12209 4,
12210 2,
12211 {TestRound(kConnect, kProxyChallenge, OK),
12212 TestRound(kConnect, kProxyChallenge, OK),
12213 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12214 &kServerChallenge),
12215 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512216 };
12217
asanka463ca4262016-11-16 02:34:3112218 for (const auto& test_config : test_configs) {
12219 SCOPED_TRACE(::testing::Message() << "Test config at "
12220 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812221 HttpAuthHandlerMock::Factory* auth_factory(
12222 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712223 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912224 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612225
12226 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512227 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112228 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812229 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12230 std::string auth_challenge = "Mock realm=proxy";
12231 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412232 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12233 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812234 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012235 empty_ssl_info, origin,
12236 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812237 auth_handler->SetGenerateExpectation(
12238 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112239 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812240 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12241 }
[email protected]044de0642010-06-17 10:42:1512242 }
12243 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012244 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512245 std::string auth_challenge = "Mock realm=server";
12246 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412247 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12248 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512249 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012250 empty_ssl_info, origin,
12251 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512252 auth_handler->SetGenerateExpectation(
12253 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112254 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812255 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612256
12257 // The second handler always succeeds. It should only be used where there
12258 // are multiple auth sessions for server auth in the same network
12259 // transaction using the same auth scheme.
12260 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12261 base::MakeUnique<HttpAuthHandlerMock>();
12262 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12263 empty_ssl_info, origin,
12264 NetLogWithSource());
12265 second_handler->SetGenerateExpectation(true, OK);
12266 auth_factory->AddMockHandler(second_handler.release(),
12267 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512268 }
12269 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312270 session_deps_.proxy_service =
12271 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512272 } else {
rdsmith82957ad2015-09-16 19:42:0312273 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512274 }
12275
12276 HttpRequestInfo request;
12277 request.method = "GET";
12278 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512279
danakj1fd259a02016-04-16 03:17:0912280 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512281
rchcb68dc62015-05-21 04:45:3612282 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12283
12284 std::vector<std::vector<MockRead>> mock_reads(1);
12285 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512286 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212287 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512288 const TestRound& read_write_round = test_config.rounds[round];
12289
12290 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612291 mock_reads.back().push_back(read_write_round.read);
12292 mock_writes.back().push_back(read_write_round.write);
12293
12294 // kProxyChallenge uses Proxy-Connection: close which means that the
12295 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412296 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612297 mock_reads.push_back(std::vector<MockRead>());
12298 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512299 }
12300
rchcb68dc62015-05-21 04:45:3612301 if (read_write_round.extra_read) {
12302 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512303 }
rchcb68dc62015-05-21 04:45:3612304 if (read_write_round.extra_write) {
12305 mock_writes.back().push_back(*read_write_round.extra_write);
12306 }
[email protected]044de0642010-06-17 10:42:1512307
12308 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512309 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712310 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512311 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612312 }
[email protected]044de0642010-06-17 10:42:1512313
danakj1fd259a02016-04-16 03:17:0912314 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612315 for (size_t i = 0; i < mock_reads.size(); ++i) {
bnc87dcefc2017-05-25 12:47:5812316 data_providers.push_back(base::MakeUnique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412317 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812318 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612319 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212320 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612321 }
12322
mmenkecc2298e2015-12-07 18:20:1812323 // Transaction must be created after DataProviders, so it's destroyed before
12324 // they are as well.
12325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12326
rchcb68dc62015-05-21 04:45:3612327 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212328 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612329 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512330 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112331 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512332 int rv;
12333 if (round == 0) {
tfarina42834112016-09-22 13:38:2012334 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512335 } else {
[email protected]49639fa2011-12-20 23:22:4112336 rv = trans.RestartWithAuth(
12337 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512338 }
12339 if (rv == ERR_IO_PENDING)
12340 rv = callback.WaitForResult();
12341
12342 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612343 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012344 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512345 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512346 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12347 continue;
12348 }
12349 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212350 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512351 } else {
wezca1070932016-05-26 20:30:5212352 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612353 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512354 }
12355 }
[email protected]e5ae96a2010-04-14 20:12:4512356 }
12357}
12358
bncd16676a2016-07-20 16:23:0112359TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412360 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412361 HttpAuthHandlerMock::Factory* auth_factory(
12362 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712363 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312364 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712365 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12366 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412367
12368 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12369 auth_handler->set_connection_based(true);
12370 std::string auth_challenge = "Mock realm=server";
12371 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412372 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12373 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912374 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412375 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012376 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812377 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412378
[email protected]c871bce92010-07-15 21:51:1412379 int rv = OK;
12380 const HttpResponseInfo* response = NULL;
12381 HttpRequestInfo request;
12382 request.method = "GET";
12383 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712384
danakj1fd259a02016-04-16 03:17:0912385 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012386
12387 // Use a TCP Socket Pool with only one connection per group. This is used
12388 // to validate that the TCP socket is not released to the pool between
12389 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212390 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812391 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012392 50, // Max sockets for pool
12393 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112394 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12395 NULL, session_deps_.net_log);
bnc87dcefc2017-05-25 12:47:5812396 auto mock_pool_manager = base::MakeUnique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212397 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812398 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012399
bnc691fda62016-08-12 00:43:1612400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112401 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412402
12403 const MockWrite kGet(
12404 "GET / HTTP/1.1\r\n"
12405 "Host: www.example.com\r\n"
12406 "Connection: keep-alive\r\n\r\n");
12407 const MockWrite kGetAuth(
12408 "GET / HTTP/1.1\r\n"
12409 "Host: www.example.com\r\n"
12410 "Connection: keep-alive\r\n"
12411 "Authorization: auth_token\r\n\r\n");
12412
12413 const MockRead kServerChallenge(
12414 "HTTP/1.1 401 Unauthorized\r\n"
12415 "WWW-Authenticate: Mock realm=server\r\n"
12416 "Content-Type: text/html; charset=iso-8859-1\r\n"
12417 "Content-Length: 14\r\n\r\n"
12418 "Unauthorized\r\n");
12419 const MockRead kSuccess(
12420 "HTTP/1.1 200 OK\r\n"
12421 "Content-Type: text/html; charset=iso-8859-1\r\n"
12422 "Content-Length: 3\r\n\r\n"
12423 "Yes");
12424
12425 MockWrite writes[] = {
12426 // First round
12427 kGet,
12428 // Second round
12429 kGetAuth,
12430 // Third round
12431 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012432 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012433 kGetAuth,
12434 // Competing request
12435 kGet,
[email protected]c871bce92010-07-15 21:51:1412436 };
12437 MockRead reads[] = {
12438 // First round
12439 kServerChallenge,
12440 // Second round
12441 kServerChallenge,
12442 // Third round
[email protected]eca50e122010-09-11 14:03:3012443 kServerChallenge,
12444 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412445 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012446 // Competing response
12447 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412448 };
12449 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12450 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712451 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412452
thestig9d3bb0c2015-01-24 00:49:5112453 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012454
12455 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412456 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012457 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412458 if (rv == ERR_IO_PENDING)
12459 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112460 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612461 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212462 ASSERT_TRUE(response);
12463 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812464 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112465 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12466 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412467
[email protected]7ef4cbbb2011-02-06 11:19:1012468 // In between rounds, another request comes in for the same domain.
12469 // It should not be able to grab the TCP socket that trans has already
12470 // claimed.
bnc691fda62016-08-12 00:43:1612471 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112472 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012473 rv = trans_compete.Start(&request, callback_compete.callback(),
12474 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012476 // callback_compete.WaitForResult at this point would stall forever,
12477 // since the HttpNetworkTransaction does not release the request back to
12478 // the pool until after authentication completes.
12479
12480 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412481 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612482 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412483 if (rv == ERR_IO_PENDING)
12484 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112485 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612486 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212487 ASSERT_TRUE(response);
12488 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812489 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112490 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12491 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412492
[email protected]7ef4cbbb2011-02-06 11:19:1012493 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412494 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612495 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412496 if (rv == ERR_IO_PENDING)
12497 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112498 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612499 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212500 ASSERT_TRUE(response);
12501 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812502 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112503 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12504 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012505
[email protected]7ef4cbbb2011-02-06 11:19:1012506 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012507 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612508 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012509 if (rv == ERR_IO_PENDING)
12510 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112511 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612512 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212513 ASSERT_TRUE(response);
12514 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812515 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012516
asanka463ca4262016-11-16 02:34:3112517 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12518 // auth handler should transition to a DONE state in concert with the remote
12519 // server. But that's not something we can test here with a mock handler.
12520 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12521 auth_handler->state());
12522
[email protected]7ef4cbbb2011-02-06 11:19:1012523 // Read the body since the fourth round was successful. This will also
12524 // release the socket back to the pool.
12525 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612526 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012527 if (rv == ERR_IO_PENDING)
12528 rv = callback.WaitForResult();
12529 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612530 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012531 EXPECT_EQ(0, rv);
12532 // There are still 0 idle sockets, since the trans_compete transaction
12533 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812534 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012535
12536 // The competing request can now finish. Wait for the headers and then
12537 // read the body.
12538 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112539 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612540 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012541 if (rv == ERR_IO_PENDING)
12542 rv = callback.WaitForResult();
12543 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612544 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012545 EXPECT_EQ(0, rv);
12546
12547 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812548 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412549}
12550
[email protected]65041fa2010-05-21 06:56:5312551// This tests the case that a request is issued via http instead of spdy after
12552// npn is negotiated.
bncd16676a2016-07-20 16:23:0112553TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312554 HttpRequestInfo request;
12555 request.method = "GET";
bncce36dca22015-04-21 22:11:2312556 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312557
12558 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312559 MockWrite(
12560 "GET / HTTP/1.1\r\n"
12561 "Host: www.example.org\r\n"
12562 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312563 };
12564
12565 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212566 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312567 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212568 MockRead("\r\n"),
12569 MockRead("hello world"),
12570 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312571 };
12572
[email protected]8ddf8322012-02-23 18:08:0612573 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612574 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312575
[email protected]bb88e1d32013-05-03 23:11:0712576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312577
12578 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12579 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712580 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312581
[email protected]49639fa2011-12-20 23:22:4112582 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312583
danakj1fd259a02016-04-16 03:17:0912584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312586
tfarina42834112016-09-22 13:38:2012587 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312588
robpercival214763f2016-07-01 23:27:0112589 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12590 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312591
bnc691fda62016-08-12 00:43:1612592 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212593 ASSERT_TRUE(response);
12594 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312595 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12596
12597 std::string response_data;
bnc691fda62016-08-12 00:43:1612598 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312599 EXPECT_EQ("hello world", response_data);
12600
12601 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212602 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312603}
[email protected]26ef6582010-06-24 02:30:4712604
bnc55ff9da2015-08-19 18:42:3512605// Simulate the SSL handshake completing with an NPN negotiation followed by an
12606// immediate server closing of the socket.
12607// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112608TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712609 HttpRequestInfo request;
12610 request.method = "GET";
bncce36dca22015-04-21 22:11:2312611 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712612
[email protected]8ddf8322012-02-23 18:08:0612613 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612614 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712616
bncdf80d44fd2016-07-15 20:27:4112617 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912618 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112619 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712620
12621 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612622 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712623 };
12624
rch8e6c6c42015-05-01 14:05:1312625 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12626 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712627 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712628
[email protected]49639fa2011-12-20 23:22:4112629 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712630
danakj1fd259a02016-04-16 03:17:0912631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712633
tfarina42834112016-09-22 13:38:2012634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12636 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712637}
[email protected]65d34382010-07-01 18:12:2612638
[email protected]795cbf82013-07-22 09:37:2712639// A subclass of HttpAuthHandlerMock that records the request URL when
12640// it gets it. This is needed since the auth handler may get destroyed
12641// before we get a chance to query it.
12642class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12643 public:
12644 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12645
dchengb03027d2014-10-21 12:00:2012646 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712647
12648 protected:
dchengb03027d2014-10-21 12:00:2012649 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12650 const HttpRequestInfo* request,
12651 const CompletionCallback& callback,
12652 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712653 *url_ = request->url;
12654 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12655 credentials, request, callback, auth_token);
12656 }
12657
12658 private:
12659 GURL* url_;
12660};
12661
[email protected]8e6441ca2010-08-19 05:56:3812662// Test that if we cancel the transaction as the connection is completing, that
12663// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112664TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812665 // Setup everything about the connection to complete synchronously, so that
12666 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12667 // for is the callback from the HttpStreamRequest.
12668 // Then cancel the transaction.
12669 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612670 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812671 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612672 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12673 MockRead(SYNCHRONOUS, "hello world"),
12674 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812675 };
12676
[email protected]8e6441ca2010-08-19 05:56:3812677 HttpRequestInfo request;
12678 request.method = "GET";
bncce36dca22015-04-21 22:11:2312679 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812680
[email protected]bb88e1d32013-05-03 23:11:0712681 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912682 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812683 auto trans =
12684 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2712685
[email protected]8e6441ca2010-08-19 05:56:3812686 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12687 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712688 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812689
[email protected]49639fa2011-12-20 23:22:4112690 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812691
vishal.b62985ca92015-04-17 08:45:5112692 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112693 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812695 trans.reset(); // Cancel the transaction here.
12696
fdoray92e35a72016-06-10 15:54:5512697 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012698}
12699
[email protected]ecab6e052014-05-16 14:58:1212700// Test that if a transaction is cancelled after receiving the headers, the
12701// stream is drained properly and added back to the socket pool. The main
12702// purpose of this test is to make sure that an HttpStreamParser can be read
12703// from after the HttpNetworkTransaction and the objects it owns have been
12704// deleted.
12705// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112706TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212707 MockRead data_reads[] = {
12708 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12709 MockRead(ASYNC, "Content-Length: 2\r\n"),
12710 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12711 MockRead(ASYNC, "1"),
12712 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12713 // HttpNetworkTransaction has been deleted.
12714 MockRead(ASYNC, "2"),
12715 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12716 };
12717 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12718 session_deps_.socket_factory->AddSocketDataProvider(&data);
12719
danakj1fd259a02016-04-16 03:17:0912720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212721
12722 {
12723 HttpRequestInfo request;
12724 request.method = "GET";
bncce36dca22015-04-21 22:11:2312725 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212726
dcheng48459ac22014-08-26 00:46:4112727 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212728 TestCompletionCallback callback;
12729
tfarina42834112016-09-22 13:38:2012730 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212732 callback.WaitForResult();
12733
12734 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212735 ASSERT_TRUE(response);
12736 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212737 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12738
12739 // The transaction and HttpRequestInfo are deleted.
12740 }
12741
12742 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512743 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212744
12745 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112746 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212747}
12748
[email protected]76a505b2010-08-25 06:23:0012749// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112750TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312751 session_deps_.proxy_service =
12752 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112753 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712754 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012756
[email protected]76a505b2010-08-25 06:23:0012757 HttpRequestInfo request;
12758 request.method = "GET";
bncce36dca22015-04-21 22:11:2312759 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012760
12761 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312762 MockWrite(
12763 "GET http://www.example.org/ HTTP/1.1\r\n"
12764 "Host: www.example.org\r\n"
12765 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012766 };
12767
12768 MockRead data_reads1[] = {
12769 MockRead("HTTP/1.1 200 OK\r\n"),
12770 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12771 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612772 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012773 };
12774
12775 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12776 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712777 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012778
[email protected]49639fa2011-12-20 23:22:4112779 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012780
bnc691fda62016-08-12 00:43:1612781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912782 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612783 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912784 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12785 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012786
bnc691fda62016-08-12 00:43:1612787 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112788 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012789
12790 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112791 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012792
bnc691fda62016-08-12 00:43:1612793 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212794 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012795
12796 EXPECT_TRUE(response->headers->IsKeepAlive());
12797 EXPECT_EQ(200, response->headers->response_code());
12798 EXPECT_EQ(100, response->headers->GetContentLength());
12799 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712800 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12801 HostPortPair::FromString("myproxy:70")),
12802 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912803 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12804 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12805 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012806 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012807
12808 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612809 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012810 TestLoadTimingNotReusedWithPac(load_timing_info,
12811 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012812}
12813
12814// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112815TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312816 session_deps_.proxy_service =
12817 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112818 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712819 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012821
[email protected]76a505b2010-08-25 06:23:0012822 HttpRequestInfo request;
12823 request.method = "GET";
bncce36dca22015-04-21 22:11:2312824 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012825
12826 // Since we have proxy, should try to establish tunnel.
12827 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712828 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12829 "Host: www.example.org:443\r\n"
12830 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012831
rsleevidb16bb02015-11-12 23:47:1712832 MockWrite("GET / HTTP/1.1\r\n"
12833 "Host: www.example.org\r\n"
12834 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012835 };
12836
12837 MockRead data_reads1[] = {
12838 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12839
12840 MockRead("HTTP/1.1 200 OK\r\n"),
12841 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12842 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612843 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012844 };
12845
12846 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12847 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712848 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612849 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712850 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012851
[email protected]49639fa2011-12-20 23:22:4112852 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012853
bnc691fda62016-08-12 00:43:1612854 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912855 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612856 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912857 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12858 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012859
bnc691fda62016-08-12 00:43:1612860 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012862
12863 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112864 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612865 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012866 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012867 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012868 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12869 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012870 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012871 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012872 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12873 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012874
bnc691fda62016-08-12 00:43:1612875 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212876 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012877
12878 EXPECT_TRUE(response->headers->IsKeepAlive());
12879 EXPECT_EQ(200, response->headers->response_code());
12880 EXPECT_EQ(100, response->headers->GetContentLength());
12881 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12882 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712883 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12884 HostPortPair::FromString("myproxy:70")),
12885 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912886 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12887 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12888 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012889
12890 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612891 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012892 TestLoadTimingNotReusedWithPac(load_timing_info,
12893 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012894}
12895
rsleevidb16bb02015-11-12 23:47:1712896// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12897// literal host.
bncd16676a2016-07-20 16:23:0112898TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712899 session_deps_.proxy_service =
12900 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12901 BoundTestNetLog log;
12902 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712904
12905 HttpRequestInfo request;
12906 request.method = "GET";
12907 request.url = GURL("https://[::1]:443/");
12908
12909 // Since we have proxy, should try to establish tunnel.
12910 MockWrite data_writes1[] = {
12911 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12912 "Host: [::1]:443\r\n"
12913 "Proxy-Connection: keep-alive\r\n\r\n"),
12914
12915 MockWrite("GET / HTTP/1.1\r\n"
12916 "Host: [::1]\r\n"
12917 "Connection: keep-alive\r\n\r\n"),
12918 };
12919
12920 MockRead data_reads1[] = {
12921 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12922
12923 MockRead("HTTP/1.1 200 OK\r\n"),
12924 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12925 MockRead("Content-Length: 100\r\n\r\n"),
12926 MockRead(SYNCHRONOUS, OK),
12927 };
12928
12929 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12930 data_writes1, arraysize(data_writes1));
12931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12932 SSLSocketDataProvider ssl(ASYNC, OK);
12933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12934
12935 TestCompletionCallback callback1;
12936
bnc691fda62016-08-12 00:43:1612937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712938
bnc691fda62016-08-12 00:43:1612939 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712941
12942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112943 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712944 TestNetLogEntry::List entries;
12945 log.GetEntries(&entries);
12946 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012947 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12948 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712949 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012950 entries, pos,
12951 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12952 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712953
bnc691fda62016-08-12 00:43:1612954 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212955 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712956
12957 EXPECT_TRUE(response->headers->IsKeepAlive());
12958 EXPECT_EQ(200, response->headers->response_code());
12959 EXPECT_EQ(100, response->headers->GetContentLength());
12960 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12961 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712962 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12963 HostPortPair::FromString("myproxy:70")),
12964 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712965
12966 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612967 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712968 TestLoadTimingNotReusedWithPac(load_timing_info,
12969 CONNECT_TIMING_HAS_SSL_TIMES);
12970}
12971
[email protected]76a505b2010-08-25 06:23:0012972// Test a basic HTTPS GET request through a proxy, but the server hangs up
12973// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112974TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312975 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112976 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712977 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912978 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012979
[email protected]76a505b2010-08-25 06:23:0012980 HttpRequestInfo request;
12981 request.method = "GET";
bncce36dca22015-04-21 22:11:2312982 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012983
12984 // Since we have proxy, should try to establish tunnel.
12985 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712986 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12987 "Host: www.example.org:443\r\n"
12988 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012989
rsleevidb16bb02015-11-12 23:47:1712990 MockWrite("GET / HTTP/1.1\r\n"
12991 "Host: www.example.org\r\n"
12992 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012993 };
12994
12995 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612996 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012997 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612998 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012999 };
13000
13001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13002 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713003 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613004 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013006
[email protected]49639fa2011-12-20 23:22:4113007 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013008
bnc691fda62016-08-12 00:43:1613009 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013010
bnc691fda62016-08-12 00:43:1613011 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013013
13014 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113015 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613016 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013017 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013018 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013019 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13020 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013021 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013022 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013023 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13024 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013025}
13026
[email protected]749eefa82010-09-13 22:14:0313027// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113028TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113029 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913030 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113031 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313032
bnc42331402016-07-25 13:36:1513033 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113034 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313035 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113036 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313037 };
13038
rch8e6c6c42015-05-01 14:05:1313039 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13040 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713041 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313042
[email protected]8ddf8322012-02-23 18:08:0613043 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613044 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313046
danakj1fd259a02016-04-16 03:17:0913047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313048
13049 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313050 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013051 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313052 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713053 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513054 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313055
13056 HttpRequestInfo request;
13057 request.method = "GET";
bncce36dca22015-04-21 22:11:2313058 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313059
13060 // This is the important line that marks this as a preconnect.
13061 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13062
bnc691fda62016-08-12 00:43:1613063 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313064
[email protected]41d64e82013-07-03 22:44:2613065 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013066 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13068 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313069}
13070
[email protected]73b8dd222010-11-11 19:55:2413071// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613072// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213073void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713074 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913075 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713076 request_info.url = GURL("https://www.example.com/");
13077 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913078 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713079
[email protected]8ddf8322012-02-23 18:08:0613080 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913081 MockWrite data_writes[] = {
13082 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413083 };
ttuttle859dc7a2015-04-23 19:42:2913084 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713085 session_deps_.socket_factory->AddSocketDataProvider(&data);
13086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413087
danakj1fd259a02016-04-16 03:17:0913088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413090
[email protected]49639fa2011-12-20 23:22:4113091 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013092 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913093 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413094 rv = callback.WaitForResult();
13095 ASSERT_EQ(error, rv);
13096}
13097
bncd16676a2016-07-20 16:23:0113098TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413099 // Just check a grab bag of cert errors.
13100 static const int kErrors[] = {
13101 ERR_CERT_COMMON_NAME_INVALID,
13102 ERR_CERT_AUTHORITY_INVALID,
13103 ERR_CERT_DATE_INVALID,
13104 };
13105 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613106 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13107 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413108 }
13109}
13110
[email protected]bd0b6772011-01-11 19:59:3013111// Ensure that a client certificate is removed from the SSL client auth
13112// cache when:
13113// 1) No proxy is involved.
13114// 2) TLS False Start is disabled.
13115// 3) The initial TLS handshake requests a client certificate.
13116// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113117TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913118 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713119 request_info.url = GURL("https://www.example.com/");
13120 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913121 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713122
[email protected]bd0b6772011-01-11 19:59:3013123 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113124 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013125
13126 // [ssl_]data1 contains the data for the first SSL handshake. When a
13127 // CertificateRequest is received for the first time, the handshake will
13128 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913129 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013130 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713131 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913132 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713133 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013134
13135 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13136 // False Start is not being used, the result of the SSL handshake will be
13137 // returned as part of the SSLClientSocket::Connect() call. This test
13138 // matches the result of a server sending a handshake_failure alert,
13139 // rather than a Finished message, because it requires a client
13140 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913141 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013142 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713143 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913144 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713145 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013146
13147 // [ssl_]data3 contains the data for the third SSL handshake. When a
13148 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213149 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13150 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013151 // of the HttpNetworkTransaction. Because this test failure is due to
13152 // requiring a client certificate, this fallback handshake should also
13153 // fail.
ttuttle859dc7a2015-04-23 19:42:2913154 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013155 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713156 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913157 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713158 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013159
[email protected]80c75f682012-05-26 16:22:1713160 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13161 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213162 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13163 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713164 // of the HttpNetworkTransaction. Because this test failure is due to
13165 // requiring a client certificate, this fallback handshake should also
13166 // fail.
ttuttle859dc7a2015-04-23 19:42:2913167 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713168 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713169 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913170 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713171 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713172
danakj1fd259a02016-04-16 03:17:0913173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013175
[email protected]bd0b6772011-01-11 19:59:3013176 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113177 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013178 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113179 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013180
13181 // Complete the SSL handshake, which should abort due to requiring a
13182 // client certificate.
13183 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113184 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013185
13186 // Indicate that no certificate should be supplied. From the perspective
13187 // of SSLClientCertCache, NULL is just as meaningful as a real
13188 // certificate, so this is the same as supply a
13189 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613190 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113191 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013192
13193 // Ensure the certificate was added to the client auth cache before
13194 // allowing the connection to continue restarting.
13195 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413196 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113197 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413198 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213199 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013200
13201 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713202 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13203 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113205 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013206
13207 // Ensure that the client certificate is removed from the cache on a
13208 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113209 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413210 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013211}
13212
13213// Ensure that a client certificate is removed from the SSL client auth
13214// cache when:
13215// 1) No proxy is involved.
13216// 2) TLS False Start is enabled.
13217// 3) The initial TLS handshake requests a client certificate.
13218// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113219TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913220 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713221 request_info.url = GURL("https://www.example.com/");
13222 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913223 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713224
[email protected]bd0b6772011-01-11 19:59:3013225 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113226 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013227
13228 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13229 // return successfully after reading up to the peer's Certificate message.
13230 // This is to allow the caller to call SSLClientSocket::Write(), which can
13231 // enqueue application data to be sent in the same packet as the
13232 // ChangeCipherSpec and Finished messages.
13233 // The actual handshake will be finished when SSLClientSocket::Read() is
13234 // called, which expects to process the peer's ChangeCipherSpec and
13235 // Finished messages. If there was an error negotiating with the peer,
13236 // such as due to the peer requiring a client certificate when none was
13237 // supplied, the alert sent by the peer won't be processed until Read() is
13238 // called.
13239
13240 // Like the non-False Start case, when a client certificate is requested by
13241 // the peer, the handshake is aborted during the Connect() call.
13242 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913243 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013244 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913246 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713247 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013248
13249 // When a client certificate is supplied, Connect() will not be aborted
13250 // when the peer requests the certificate. Instead, the handshake will
13251 // artificially succeed, allowing the caller to write the HTTP request to
13252 // the socket. The handshake messages are not processed until Read() is
13253 // called, which then detects that the handshake was aborted, due to the
13254 // peer sending a handshake_failure because it requires a client
13255 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913256 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013257 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913259 MockRead data2_reads[] = {
13260 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013261 };
ttuttle859dc7a2015-04-23 19:42:2913262 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713263 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013264
13265 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713266 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13267 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913268 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013269 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913271 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713272 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013273
[email protected]80c75f682012-05-26 16:22:1713274 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13275 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913276 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713277 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713278 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913279 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713280 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713281
[email protected]7799de12013-05-30 05:52:5113282 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913283 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113284 ssl_data5.cert_request_info = cert_request.get();
13285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913286 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113287 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13288
danakj1fd259a02016-04-16 03:17:0913289 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613290 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013291
[email protected]bd0b6772011-01-11 19:59:3013292 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113293 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013294 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113295 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013296
13297 // Complete the SSL handshake, which should abort due to requiring a
13298 // client certificate.
13299 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113300 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013301
13302 // Indicate that no certificate should be supplied. From the perspective
13303 // of SSLClientCertCache, NULL is just as meaningful as a real
13304 // certificate, so this is the same as supply a
13305 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613306 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113307 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013308
13309 // Ensure the certificate was added to the client auth cache before
13310 // allowing the connection to continue restarting.
13311 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413312 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113313 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413314 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213315 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013316
[email protected]bd0b6772011-01-11 19:59:3013317 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713318 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13319 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013320 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113321 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013322
13323 // Ensure that the client certificate is removed from the cache on a
13324 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113325 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413326 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013327}
13328
[email protected]8c405132011-01-11 22:03:1813329// Ensure that a client certificate is removed from the SSL client auth
13330// cache when:
13331// 1) An HTTPS proxy is involved.
13332// 3) The HTTPS proxy requests a client certificate.
13333// 4) The client supplies an invalid/unacceptable certificate for the
13334// proxy.
13335// The test is repeated twice, first for connecting to an HTTPS endpoint,
13336// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113337TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313338 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113339 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713340 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813341
13342 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113343 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813344
13345 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13346 // [ssl_]data[1-3]. Rather than represending the endpoint
13347 // (www.example.com:443), they represent failures with the HTTPS proxy
13348 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913349 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813350 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913352 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713353 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813354
ttuttle859dc7a2015-04-23 19:42:2913355 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813356 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913358 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713359 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813360
[email protected]80c75f682012-05-26 16:22:1713361 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13362#if 0
ttuttle859dc7a2015-04-23 19:42:2913363 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813364 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913366 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713367 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713368#endif
[email protected]8c405132011-01-11 22:03:1813369
ttuttle859dc7a2015-04-23 19:42:2913370 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813371 requests[0].url = GURL("https://www.example.com/");
13372 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913373 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813374
13375 requests[1].url = GURL("http://www.example.com/");
13376 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913377 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813378
13379 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713380 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913381 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613382 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813383
13384 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113385 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013386 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113387 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813388
13389 // Complete the SSL handshake, which should abort due to requiring a
13390 // client certificate.
13391 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113392 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813393
13394 // Indicate that no certificate should be supplied. From the perspective
13395 // of SSLClientCertCache, NULL is just as meaningful as a real
13396 // certificate, so this is the same as supply a
13397 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613398 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113399 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813400
13401 // Ensure the certificate was added to the client auth cache before
13402 // allowing the connection to continue restarting.
13403 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413404 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113405 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413406 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213407 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813408 // Ensure the certificate was NOT cached for the endpoint. This only
13409 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113410 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413411 HostPortPair("www.example.com", 443), &client_cert,
13412 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813413
13414 // Restart the handshake. This will consume ssl_data2, which fails, and
13415 // then consume ssl_data3, which should also fail. The result code is
13416 // checked against what ssl_data3 should return.
13417 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113418 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813419
13420 // Now that the new handshake has failed, ensure that the client
13421 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113422 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413423 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113424 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413425 HostPortPair("www.example.com", 443), &client_cert,
13426 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813427 }
13428}
13429
bncd16676a2016-07-20 16:23:0113430TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613431 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813432 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913433 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613434
bnc032658ba2016-09-26 18:17:1513435 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613436
bncdf80d44fd2016-07-15 20:27:4113437 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913438 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813439 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113440 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713441 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613442 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113443 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613444 };
bnc42331402016-07-25 13:36:1513445 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113446 SpdySerializedFrame host1_resp_body(
13447 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513448 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113449 SpdySerializedFrame host2_resp_body(
13450 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613451 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113452 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13453 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313454 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613455 };
13456
eroman36d84e54432016-03-17 03:23:0213457 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213458 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313459 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13460 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713461 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613462
[email protected]aa22b242011-11-16 18:58:2913463 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613464 HttpRequestInfo request1;
13465 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313466 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613467 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013468 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613469
tfarina42834112016-09-22 13:38:2013470 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13472 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613473
13474 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213475 ASSERT_TRUE(response);
13476 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213477 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613478
13479 std::string response_data;
robpercival214763f2016-07-01 23:27:0113480 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613481 EXPECT_EQ("hello!", response_data);
13482
bnca4d611d2016-09-22 19:55:3713483 // Preload mail.example.com into HostCache.
13484 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013485 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613486 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013487 std::unique_ptr<HostResolver::Request> request;
13488 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13489 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013490 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713492 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113493 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613494
13495 HttpRequestInfo request2;
13496 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713497 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613498 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013499 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613500
tfarina42834112016-09-22 13:38:2013501 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13503 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613504
13505 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213506 ASSERT_TRUE(response);
13507 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213508 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613509 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213510 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113511 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613512 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613513}
13514
bncd16676a2016-07-20 16:23:0113515TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213516 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
bnc87dcefc2017-05-25 12:47:5813517 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913518 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213519
bnc032658ba2016-09-26 18:17:1513520 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213521
bncdf80d44fd2016-07-15 20:27:4113522 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913523 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813524 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113525 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713526 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213527 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113528 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213529 };
bnc42331402016-07-25 13:36:1513530 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113531 SpdySerializedFrame host1_resp_body(
13532 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513533 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113534 SpdySerializedFrame host2_resp_body(
13535 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213536 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113537 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13538 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313539 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213540 };
13541
eroman36d84e54432016-03-17 03:23:0213542 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213543 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313544 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13545 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713546 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213547
13548 TestCompletionCallback callback;
13549 HttpRequestInfo request1;
13550 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313551 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213552 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013553 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213554
tfarina42834112016-09-22 13:38:2013555 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13557 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213558
13559 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213560 ASSERT_TRUE(response);
13561 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213562 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213563
13564 std::string response_data;
robpercival214763f2016-07-01 23:27:0113565 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213566 EXPECT_EQ("hello!", response_data);
13567
13568 HttpRequestInfo request2;
13569 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713570 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213571 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013572 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213573
tfarina42834112016-09-22 13:38:2013574 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13576 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213577
13578 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213579 ASSERT_TRUE(response);
13580 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213581 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213582 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213583 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113584 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213585 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213586}
13587
bnc8016c1f2017-03-31 02:11:2913588// Regression test for https://crbug.com/546991.
13589// The server might not be able to serve an IP pooled request, and might send a
13590// 421 Misdirected Request response status to indicate this.
13591// HttpNetworkTransaction should reset the request and retry without IP pooling.
13592TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13593 // Two hosts resolve to the same IP address.
13594 const std::string ip_addr = "1.2.3.4";
13595 IPAddress ip;
13596 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13597 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13598
bnc87dcefc2017-05-25 12:47:5813599 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913600 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13601 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13602
13603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13604
13605 // Two requests on the first connection.
13606 SpdySerializedFrame req1(
13607 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13608 spdy_util_.UpdateWithStreamDestruction(1);
13609 SpdySerializedFrame req2(
13610 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13611 SpdySerializedFrame rst(
13612 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13613 MockWrite writes1[] = {
13614 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13615 CreateMockWrite(rst, 6),
13616 };
13617
13618 // The first one succeeds, the second gets error 421 Misdirected Request.
13619 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13620 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13621 SpdyHeaderBlock response_headers;
13622 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13623 SpdySerializedFrame resp2(
13624 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13625 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13626 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13627
13628 MockConnect connect1(ASYNC, OK, peer_addr);
13629 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13630 arraysize(writes1));
13631 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13632
13633 AddSSLSocketData();
13634
13635 // Retry the second request on a second connection.
13636 SpdyTestUtil spdy_util2;
13637 SpdySerializedFrame req3(
13638 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13639 MockWrite writes2[] = {
13640 CreateMockWrite(req3, 0),
13641 };
13642
13643 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13644 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13645 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13646 MockRead(ASYNC, 0, 3)};
13647
13648 MockConnect connect2(ASYNC, OK, peer_addr);
13649 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13650 arraysize(writes2));
13651 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13652
13653 AddSSLSocketData();
13654
13655 // Preload mail.example.org into HostCache.
13656 HostPortPair host_port("mail.example.org", 443);
13657 HostResolver::RequestInfo resolve_info(host_port);
13658 AddressList ignored;
13659 std::unique_ptr<HostResolver::Request> request;
13660 TestCompletionCallback callback;
13661 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13662 &ignored, callback.callback(),
13663 &request, NetLogWithSource());
13664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13665 rv = callback.WaitForResult();
13666 EXPECT_THAT(rv, IsOk());
13667
13668 HttpRequestInfo request1;
13669 request1.method = "GET";
13670 request1.url = GURL("https://www.example.org/");
13671 request1.load_flags = 0;
13672 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13673
13674 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13676 rv = callback.WaitForResult();
13677 EXPECT_THAT(rv, IsOk());
13678
13679 const HttpResponseInfo* response = trans1.GetResponseInfo();
13680 ASSERT_TRUE(response);
13681 ASSERT_TRUE(response->headers);
13682 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13683 EXPECT_TRUE(response->was_fetched_via_spdy);
13684 EXPECT_TRUE(response->was_alpn_negotiated);
13685 std::string response_data;
13686 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13687 EXPECT_EQ("hello!", response_data);
13688
13689 HttpRequestInfo request2;
13690 request2.method = "GET";
13691 request2.url = GURL("https://mail.example.org/");
13692 request2.load_flags = 0;
13693 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13694
13695 BoundTestNetLog log;
13696 rv = trans2.Start(&request2, callback.callback(), log.bound());
13697 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13698 rv = callback.WaitForResult();
13699 EXPECT_THAT(rv, IsOk());
13700
13701 response = trans2.GetResponseInfo();
13702 ASSERT_TRUE(response);
13703 ASSERT_TRUE(response->headers);
13704 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13705 EXPECT_TRUE(response->was_fetched_via_spdy);
13706 EXPECT_TRUE(response->was_alpn_negotiated);
13707 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13708 EXPECT_EQ("hello!", response_data);
13709
13710 TestNetLogEntry::List entries;
13711 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5913712 ExpectLogContainsSomewhere(
13713 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2913714 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5913715}
13716
13717// Test that HTTP 421 responses are properly returned to the caller if received
13718// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
13719// portions of the response.
13720TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
13721 // Two hosts resolve to the same IP address.
13722 const std::string ip_addr = "1.2.3.4";
13723 IPAddress ip;
13724 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13725 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13726
bnc87dcefc2017-05-25 12:47:5813727 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5913728 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13729 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13730
13731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13732
13733 // Two requests on the first connection.
13734 SpdySerializedFrame req1(
13735 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13736 spdy_util_.UpdateWithStreamDestruction(1);
13737 SpdySerializedFrame req2(
13738 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13739 SpdySerializedFrame rst(
13740 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13741 MockWrite writes1[] = {
13742 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13743 CreateMockWrite(rst, 6),
13744 };
13745
13746 // The first one succeeds, the second gets error 421 Misdirected Request.
13747 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13748 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13749 SpdyHeaderBlock response_headers;
13750 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13751 SpdySerializedFrame resp2(
13752 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
13753 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13754 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13755
13756 MockConnect connect1(ASYNC, OK, peer_addr);
13757 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13758 arraysize(writes1));
13759 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13760
13761 AddSSLSocketData();
13762
13763 // Retry the second request on a second connection. It returns 421 Misdirected
13764 // Retry again.
13765 SpdyTestUtil spdy_util2;
13766 SpdySerializedFrame req3(
13767 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13768 MockWrite writes2[] = {
13769 CreateMockWrite(req3, 0),
13770 };
13771
13772 SpdySerializedFrame resp3(
13773 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
13774 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13775 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13776 MockRead(ASYNC, 0, 3)};
13777
13778 MockConnect connect2(ASYNC, OK, peer_addr);
13779 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13780 arraysize(writes2));
13781 session_deps_.socket_factory->AddSocketDataProvider(&data2);
13782
13783 AddSSLSocketData();
13784
13785 // Preload mail.example.org into HostCache.
13786 HostPortPair host_port("mail.example.org", 443);
13787 HostResolver::RequestInfo resolve_info(host_port);
13788 AddressList ignored;
13789 std::unique_ptr<HostResolver::Request> request;
13790 TestCompletionCallback callback;
13791 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13792 &ignored, callback.callback(),
13793 &request, NetLogWithSource());
13794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13795 rv = callback.WaitForResult();
13796 EXPECT_THAT(rv, IsOk());
13797
13798 HttpRequestInfo request1;
13799 request1.method = "GET";
13800 request1.url = GURL("https://www.example.org/");
13801 request1.load_flags = 0;
13802 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13803
13804 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13806 rv = callback.WaitForResult();
13807 EXPECT_THAT(rv, IsOk());
13808
13809 const HttpResponseInfo* response = trans1.GetResponseInfo();
13810 ASSERT_TRUE(response);
13811 ASSERT_TRUE(response->headers);
13812 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13813 EXPECT_TRUE(response->was_fetched_via_spdy);
13814 EXPECT_TRUE(response->was_alpn_negotiated);
13815 std::string response_data;
13816 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13817 EXPECT_EQ("hello!", response_data);
13818
13819 HttpRequestInfo request2;
13820 request2.method = "GET";
13821 request2.url = GURL("https://mail.example.org/");
13822 request2.load_flags = 0;
13823 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13824
13825 BoundTestNetLog log;
13826 rv = trans2.Start(&request2, callback.callback(), log.bound());
13827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13828 rv = callback.WaitForResult();
13829 EXPECT_THAT(rv, IsOk());
13830
13831 // After a retry, the 421 Misdirected Request is reported back up to the
13832 // caller.
13833 response = trans2.GetResponseInfo();
13834 ASSERT_TRUE(response);
13835 ASSERT_TRUE(response->headers);
13836 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
13837 EXPECT_TRUE(response->was_fetched_via_spdy);
13838 EXPECT_TRUE(response->was_alpn_negotiated);
13839 EXPECT_TRUE(response->ssl_info.cert);
13840 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13841 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2913842}
13843
bnc6dcd8192017-05-25 20:11:5013844class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4613845 public:
13846 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5013847 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013848 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613849
dchengb03027d2014-10-21 12:00:2013850 int ResolveFromCache(const RequestInfo& info,
13851 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013852 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5013853 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4013854 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5013855 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613856 return rv;
13857 }
13858
[email protected]e3ceb682011-06-28 23:55:4613859 private:
[email protected]e3ceb682011-06-28 23:55:4613860 const HostPortPair host_port_;
13861};
13862
bncd16676a2016-07-20 16:23:0113863TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313864 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613865 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnc6dcd8192017-05-25 20:11:5013866 session_deps_.host_resolver = base::MakeUnique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3713867 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0913868 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613869
bnc032658ba2016-09-26 18:17:1513870 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613871
bncdf80d44fd2016-07-15 20:27:4113872 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913873 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813874 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113875 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713876 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613877 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113878 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613879 };
bnc42331402016-07-25 13:36:1513880 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113881 SpdySerializedFrame host1_resp_body(
13882 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513883 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113884 SpdySerializedFrame host2_resp_body(
13885 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613886 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113887 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13888 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313889 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613890 };
13891
eroman36d84e54432016-03-17 03:23:0213892 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213893 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313894 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13895 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713896 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613897
[email protected]aa22b242011-11-16 18:58:2913898 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613899 HttpRequestInfo request1;
13900 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313901 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613902 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013903 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613904
tfarina42834112016-09-22 13:38:2013905 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13907 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613908
13909 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213910 ASSERT_TRUE(response);
13911 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213912 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613913
13914 std::string response_data;
robpercival214763f2016-07-01 23:27:0113915 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613916 EXPECT_EQ("hello!", response_data);
13917
13918 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713919 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613920 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013921 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5013922 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13923 &ignored, callback.callback(),
13924 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713926 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113927 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613928
13929 HttpRequestInfo request2;
13930 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713931 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613932 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013933 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613934
tfarina42834112016-09-22 13:38:2013935 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13937 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613938
13939 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213940 ASSERT_TRUE(response);
13941 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213942 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613943 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213944 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113945 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613946 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613947}
13948
bncd16676a2016-07-20 16:23:0113949TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313950 const std::string https_url = "https://www.example.org:8080/";
13951 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413952
13953 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113954 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913955 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413956
13957 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113958 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413959 };
13960
bnc42331402016-07-25 13:36:1513961 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113962 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13963 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913964 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413965
rch8e6c6c42015-05-01 14:05:1313966 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13967 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413968 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713969 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413970
13971 // HTTP GET for the HTTP URL
13972 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313973 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413974 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313975 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413976 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413977 };
13978
13979 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313980 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13981 MockRead(ASYNC, 2, "hello"),
13982 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413983 };
13984
rch8e6c6c42015-05-01 14:05:1313985 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13986 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413987
[email protected]8450d722012-07-02 19:14:0413988 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613989 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13991 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13992 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413993
danakj1fd259a02016-04-16 03:17:0913994 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413995
13996 // Start the first transaction to set up the SpdySession
13997 HttpRequestInfo request1;
13998 request1.method = "GET";
13999 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414000 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014001 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414002 TestCompletionCallback callback1;
14003 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014004 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514005 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414006
robpercival214763f2016-07-01 23:27:0114007 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414008 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14009
14010 // Now, start the HTTP request
14011 HttpRequestInfo request2;
14012 request2.method = "GET";
14013 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414014 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014015 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414016 TestCompletionCallback callback2;
14017 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014018 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514019 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414020
robpercival214763f2016-07-01 23:27:0114021 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414022 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14023}
14024
bnc5452e2a2015-05-08 16:27:4214025// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14026// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114027TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514028 url::SchemeHostPort server("https", "www.example.org", 443);
14029 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214030
bnc8bef8da22016-05-30 01:28:2514031 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214032 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614033 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214034 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14035
14036 // No data should be read from the alternative, because HTTP/1.1 is
14037 // negotiated.
14038 StaticSocketDataProvider data;
14039 session_deps_.socket_factory->AddSocketDataProvider(&data);
14040
14041 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614042 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214043 // mocked. This way the request relies on the alternate Job.
14044 StaticSocketDataProvider data_refused;
14045 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14046 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14047
zhongyi3d4a55e72016-04-22 20:36:4614048 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014050 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214051 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114052 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214053 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614054 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014055 expiration);
bnc5452e2a2015-05-08 16:27:4214056
bnc5452e2a2015-05-08 16:27:4214057 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214059 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514060 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214061 TestCompletionCallback callback;
14062
14063 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214064 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014065 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214066 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214067}
14068
bnc40448a532015-05-11 19:13:1414069// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614070// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414071// succeeds, the request should succeed, even if the latter fails because
14072// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114073TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514074 url::SchemeHostPort server("https", "www.example.org", 443);
14075 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414076
14077 // Negotiate HTTP/1.1 with alternative.
14078 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614079 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414080 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14081
14082 // No data should be read from the alternative, because HTTP/1.1 is
14083 // negotiated.
14084 StaticSocketDataProvider data;
14085 session_deps_.socket_factory->AddSocketDataProvider(&data);
14086
zhongyi3d4a55e72016-04-22 20:36:4614087 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414088 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614089 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414090 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14091
14092 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514093 MockWrite("GET / HTTP/1.1\r\n"
14094 "Host: www.example.org\r\n"
14095 "Connection: keep-alive\r\n\r\n"),
14096 MockWrite("GET /second HTTP/1.1\r\n"
14097 "Host: www.example.org\r\n"
14098 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414099 };
14100
14101 MockRead http_reads[] = {
14102 MockRead("HTTP/1.1 200 OK\r\n"),
14103 MockRead("Content-Type: text/html\r\n"),
14104 MockRead("Content-Length: 6\r\n\r\n"),
14105 MockRead("foobar"),
14106 MockRead("HTTP/1.1 200 OK\r\n"),
14107 MockRead("Content-Type: text/html\r\n"),
14108 MockRead("Content-Length: 7\r\n\r\n"),
14109 MockRead("another"),
14110 };
14111 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14112 http_writes, arraysize(http_writes));
14113 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14114
zhongyi3d4a55e72016-04-22 20:36:4614115 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914116 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014117 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414118 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114119 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214120 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614121 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014122 expiration);
bnc40448a532015-05-11 19:13:1414123
14124 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14125 HttpRequestInfo request1;
14126 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514127 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414128 request1.load_flags = 0;
14129 TestCompletionCallback callback1;
14130
tfarina42834112016-09-22 13:38:2014131 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414132 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114133 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414134
14135 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214136 ASSERT_TRUE(response1);
14137 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414138 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14139
14140 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114141 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414142 EXPECT_EQ("foobar", response_data1);
14143
14144 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14145 // for alternative service.
14146 EXPECT_TRUE(
14147 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14148
zhongyi3d4a55e72016-04-22 20:36:4614149 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414150 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614151 // to server.
bnc40448a532015-05-11 19:13:1414152 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14153 HttpRequestInfo request2;
14154 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514155 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414156 request2.load_flags = 0;
14157 TestCompletionCallback callback2;
14158
tfarina42834112016-09-22 13:38:2014159 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414160 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114161 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414162
14163 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214164 ASSERT_TRUE(response2);
14165 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414166 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14167
14168 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114169 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414170 EXPECT_EQ("another", response_data2);
14171}
14172
bnc5452e2a2015-05-08 16:27:4214173// Alternative service requires HTTP/2 (or SPDY), but there is already a
14174// HTTP/1.1 socket open to the alternative server. That socket should not be
14175// used.
bncd16676a2016-07-20 16:23:0114176TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614177 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214178 HostPortPair alternative("alternative.example.org", 443);
14179 std::string origin_url = "https://origin.example.org:443";
14180 std::string alternative_url = "https://alternative.example.org:443";
14181
14182 // Negotiate HTTP/1.1 with alternative.example.org.
14183 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614184 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14186
14187 // HTTP/1.1 data for |request1| and |request2|.
14188 MockWrite http_writes[] = {
14189 MockWrite(
14190 "GET / HTTP/1.1\r\n"
14191 "Host: alternative.example.org\r\n"
14192 "Connection: keep-alive\r\n\r\n"),
14193 MockWrite(
14194 "GET / HTTP/1.1\r\n"
14195 "Host: alternative.example.org\r\n"
14196 "Connection: keep-alive\r\n\r\n"),
14197 };
14198
14199 MockRead http_reads[] = {
14200 MockRead(
14201 "HTTP/1.1 200 OK\r\n"
14202 "Content-Type: text/html; charset=iso-8859-1\r\n"
14203 "Content-Length: 40\r\n\r\n"
14204 "first HTTP/1.1 response from alternative"),
14205 MockRead(
14206 "HTTP/1.1 200 OK\r\n"
14207 "Content-Type: text/html; charset=iso-8859-1\r\n"
14208 "Content-Length: 41\r\n\r\n"
14209 "second HTTP/1.1 response from alternative"),
14210 };
14211 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14212 http_writes, arraysize(http_writes));
14213 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14214
14215 // This test documents that an alternate Job should not pool to an already
14216 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614217 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214218 StaticSocketDataProvider data_refused;
14219 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14220 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14221
zhongyi3d4a55e72016-04-22 20:36:4614222 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014224 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214225 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114226 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214227 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4614228 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5014229 expiration);
bnc5452e2a2015-05-08 16:27:4214230
14231 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214232 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614233 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214234 request1.method = "GET";
14235 request1.url = GURL(alternative_url);
14236 request1.load_flags = 0;
14237 TestCompletionCallback callback1;
14238
tfarina42834112016-09-22 13:38:2014239 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114240 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614241 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214242 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214243 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214244 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214245 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214246 EXPECT_FALSE(response1->was_fetched_via_spdy);
14247 std::string response_data1;
bnc691fda62016-08-12 00:43:1614248 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214249 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14250
14251 // Request for origin.example.org, which has an alternative service. This
14252 // will start two Jobs: the alternative looks for connections to pool to,
14253 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614254 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214255 // this request fails.
bnc5452e2a2015-05-08 16:27:4214256 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614257 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214258 request2.method = "GET";
14259 request2.url = GURL(origin_url);
14260 request2.load_flags = 0;
14261 TestCompletionCallback callback2;
14262
tfarina42834112016-09-22 13:38:2014263 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114264 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214265
14266 // Another transaction to alternative. This is to test that the HTTP/1.1
14267 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214268 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614269 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214270 request3.method = "GET";
14271 request3.url = GURL(alternative_url);
14272 request3.load_flags = 0;
14273 TestCompletionCallback callback3;
14274
tfarina42834112016-09-22 13:38:2014275 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114276 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614277 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214278 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214279 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214280 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214281 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214282 EXPECT_FALSE(response3->was_fetched_via_spdy);
14283 std::string response_data3;
bnc691fda62016-08-12 00:43:1614284 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214285 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14286}
14287
bncd16676a2016-07-20 16:23:0114288TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314289 const std::string https_url = "https://www.example.org:8080/";
14290 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414291
rdsmithebb50aa2015-11-12 03:44:3814292 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114293 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814294
[email protected]8450d722012-07-02 19:14:0414295 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314296 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114297 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414298 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114299 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914300 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114301 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214302 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914303
14304 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914305 SpdyHeaderBlock req2_block;
14306 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314307 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914308 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914309 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114310 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514311 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414312
14313 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114314 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14315 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414316 };
14317
bncdf80d44fd2016-07-15 20:27:4114318 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514319 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114320 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514321 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114322 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14323 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814324 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114325 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814326 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514327 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114328 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314329 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114330 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314331 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114332 CreateMockRead(wrapped_resp1, 4),
14333 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314334 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114335 CreateMockRead(resp2, 8),
14336 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314337 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14338 };
[email protected]8450d722012-07-02 19:14:0414339
mmenke666a6fea2015-12-19 04:16:3314340 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14341 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414342 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714343 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414344
rdsmith82957ad2015-09-16 19:42:0314345 session_deps_.proxy_service =
14346 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114347 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714348 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414349 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614350 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414352 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614353 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14355 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414356
danakj1fd259a02016-04-16 03:17:0914357 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414358
14359 // Start the first transaction to set up the SpdySession
14360 HttpRequestInfo request1;
14361 request1.method = "GET";
14362 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414363 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014364 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414365 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014366 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414367
mmenke666a6fea2015-12-19 04:16:3314368 // This pause is a hack to avoid running into https://crbug.com/497228.
14369 data1.RunUntilPaused();
14370 base::RunLoop().RunUntilIdle();
14371 data1.Resume();
robpercival214763f2016-07-01 23:27:0114372 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414373 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14374
[email protected]f6c63db52013-02-02 00:35:2214375 LoadTimingInfo load_timing_info1;
14376 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14377 TestLoadTimingNotReusedWithPac(load_timing_info1,
14378 CONNECT_TIMING_HAS_SSL_TIMES);
14379
mmenke666a6fea2015-12-19 04:16:3314380 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414381 HttpRequestInfo request2;
14382 request2.method = "GET";
14383 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414384 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014385 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414386 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014387 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414388
mmenke666a6fea2015-12-19 04:16:3314389 // This pause is a hack to avoid running into https://crbug.com/497228.
14390 data1.RunUntilPaused();
14391 base::RunLoop().RunUntilIdle();
14392 data1.Resume();
robpercival214763f2016-07-01 23:27:0114393 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314394
[email protected]8450d722012-07-02 19:14:0414395 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214396
14397 LoadTimingInfo load_timing_info2;
14398 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14399 // The established SPDY sessions is considered reused by the HTTP request.
14400 TestLoadTimingReusedWithPac(load_timing_info2);
14401 // HTTP requests over a SPDY session should have a different connection
14402 // socket_log_id than requests over a tunnel.
14403 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414404}
14405
[email protected]2d88e7d2012-07-19 17:55:1714406// Test that in the case where we have a SPDY session to a SPDY proxy
14407// that we do not pool other origins that resolve to the same IP when
14408// the certificate does not match the new origin.
14409// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114410TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314411 const std::string url1 = "http://www.example.org/";
14412 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714413 const std::string ip_addr = "1.2.3.4";
14414
rdsmithebb50aa2015-11-12 03:44:3814415 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114416 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814417
[email protected]2d88e7d2012-07-19 17:55:1714418 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614419 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314420 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114421 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514422 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714423
14424 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114425 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714426 };
14427
bnc42331402016-07-25 13:36:1514428 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114429 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714430 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114431 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14432 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714433 };
14434
mmenke666a6fea2015-12-19 04:16:3314435 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14436 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214437 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914438 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714439 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14440 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314441 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714442
14443 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114444 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914445 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714446
14447 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114448 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714449 };
14450
bnc42331402016-07-25 13:36:1514451 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114452 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14453 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314454 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714455
mmenke666a6fea2015-12-19 04:16:3314456 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14457 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714458 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314459 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714460
14461 // Set up a proxy config that sends HTTP requests to a proxy, and
14462 // all others direct.
14463 ProxyConfig proxy_config;
14464 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
bnc87dcefc2017-05-25 12:47:5814465 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
14466 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), nullptr,
14467 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714468
bncce36dca22015-04-21 22:11:2314469 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614470 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714471 // Load a valid cert. Note, that this does not need to
14472 // be valid for proxy because the MockSSLClientSocket does
14473 // not actually verify it. But SpdySession will use this
14474 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314475 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214476 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314477 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14478 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714479
14480 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614481 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314482 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14483 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714484
bnc87dcefc2017-05-25 12:47:5814485 session_deps_.host_resolver = base::MakeUnique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314486 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714487 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714488
danakj1fd259a02016-04-16 03:17:0914489 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714490
14491 // Start the first transaction to set up the SpdySession
14492 HttpRequestInfo request1;
14493 request1.method = "GET";
14494 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714495 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014496 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714497 TestCompletionCallback callback1;
14498 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014499 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314500 // This pause is a hack to avoid running into https://crbug.com/497228.
14501 data1.RunUntilPaused();
14502 base::RunLoop().RunUntilIdle();
14503 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714504
robpercival214763f2016-07-01 23:27:0114505 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714506 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14507
14508 // Now, start the HTTP request
14509 HttpRequestInfo request2;
14510 request2.method = "GET";
14511 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714512 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014513 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714514 TestCompletionCallback callback2;
14515 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014516 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514517 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714518
14519 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114520 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714521 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14522}
14523
[email protected]85f97342013-04-17 06:12:2414524// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14525// error) in SPDY session, removes the socket from pool and closes the SPDY
14526// session. Verify that new url's from the same HttpNetworkSession (and a new
14527// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114528TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314529 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414530
14531 MockRead reads1[] = {
14532 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14533 };
14534
mmenke11eb5152015-06-09 14:50:5014535 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414536
bncdf80d44fd2016-07-15 20:27:4114537 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914538 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414539 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114540 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414541 };
14542
bnc42331402016-07-25 13:36:1514543 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114544 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414545 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114546 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14547 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414548 };
14549
mmenke11eb5152015-06-09 14:50:5014550 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14551 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414552
[email protected]85f97342013-04-17 06:12:2414553 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614554 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014555 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14556 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414557
14558 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614559 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014560 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14561 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414562
danakj1fd259a02016-04-16 03:17:0914563 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014564 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414565
14566 // Start the first transaction to set up the SpdySession and verify that
14567 // connection was closed.
14568 HttpRequestInfo request1;
14569 request1.method = "GET";
14570 request1.url = GURL(https_url);
14571 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014572 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414573 TestCompletionCallback callback1;
14574 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014575 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114576 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414577
14578 // Now, start the second request and make sure it succeeds.
14579 HttpRequestInfo request2;
14580 request2.method = "GET";
14581 request2.url = GURL(https_url);
14582 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014583 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414584 TestCompletionCallback callback2;
14585 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014586 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414587
robpercival214763f2016-07-01 23:27:0114588 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414589 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14590}
14591
bncd16676a2016-07-20 16:23:0114592TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314593 ClientSocketPoolManager::set_max_sockets_per_group(
14594 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14595 ClientSocketPoolManager::set_max_sockets_per_pool(
14596 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14597
14598 // Use two different hosts with different IPs so they don't get pooled.
14599 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14600 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314602
14603 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614604 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314605 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614606 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314607 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14609
bncdf80d44fd2016-07-15 20:27:4114610 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914611 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314612 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114613 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314614 };
bnc42331402016-07-25 13:36:1514615 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114616 SpdySerializedFrame host1_resp_body(
14617 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314618 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114619 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914620 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314621 };
14622
rdsmithebb50aa2015-11-12 03:44:3814623 // Use a separate test instance for the separate SpdySession that will be
14624 // created.
bncd16676a2016-07-20 16:23:0114625 SpdyTestUtil spdy_util_2;
bnc87dcefc2017-05-25 12:47:5814626 auto spdy1_data = base::MakeUnique<SequencedSocketData>(
14627 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14628 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0314629 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14630
bncdf80d44fd2016-07-15 20:27:4114631 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914632 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314633 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114634 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314635 };
bnc42331402016-07-25 13:36:1514636 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114637 SpdySerializedFrame host2_resp_body(
14638 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314639 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114640 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914641 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314642 };
14643
bnc87dcefc2017-05-25 12:47:5814644 auto spdy2_data = base::MakeUnique<SequencedSocketData>(
14645 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14646 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0314647 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14648
14649 MockWrite http_write[] = {
14650 MockWrite("GET / HTTP/1.1\r\n"
14651 "Host: www.a.com\r\n"
14652 "Connection: keep-alive\r\n\r\n"),
14653 };
14654
14655 MockRead http_read[] = {
14656 MockRead("HTTP/1.1 200 OK\r\n"),
14657 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14658 MockRead("Content-Length: 6\r\n\r\n"),
14659 MockRead("hello!"),
14660 };
14661 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14662 http_write, arraysize(http_write));
14663 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14664
14665 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014666 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314667 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314668 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614669 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314670
14671 TestCompletionCallback callback;
14672 HttpRequestInfo request1;
14673 request1.method = "GET";
14674 request1.url = GURL("https://www.a.com/");
14675 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814676 auto trans =
14677 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314678
tfarina42834112016-09-22 13:38:2014679 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14681 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314682
14683 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214684 ASSERT_TRUE(response);
14685 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214686 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314687 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214688 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314689
14690 std::string response_data;
robpercival214763f2016-07-01 23:27:0114691 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314692 EXPECT_EQ("hello!", response_data);
14693 trans.reset();
14694 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614695 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314696
14697 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014698 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314699 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314700 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614701 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314702 HttpRequestInfo request2;
14703 request2.method = "GET";
14704 request2.url = GURL("https://www.b.com/");
14705 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814706 trans =
14707 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314708
tfarina42834112016-09-22 13:38:2014709 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14711 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314712
14713 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214714 ASSERT_TRUE(response);
14715 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214716 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314717 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214718 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114719 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314720 EXPECT_EQ("hello!", response_data);
14721 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614722 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314723 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614724 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314725
14726 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014727 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314728 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314729 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614730 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314731 HttpRequestInfo request3;
14732 request3.method = "GET";
14733 request3.url = GURL("http://www.a.com/");
14734 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5814735 trans =
14736 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0314737
tfarina42834112016-09-22 13:38:2014738 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114739 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14740 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314741
14742 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214743 ASSERT_TRUE(response);
14744 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314745 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14746 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214747 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114748 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314749 EXPECT_EQ("hello!", response_data);
14750 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614751 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314752 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614753 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314754}
14755
bncd16676a2016-07-20 16:23:0114756TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414757 HttpRequestInfo request;
14758 request.method = "GET";
bncce36dca22015-04-21 22:11:2314759 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414760
danakj1fd259a02016-04-16 03:17:0914761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414763
ttuttled9dbc652015-09-29 20:00:5914764 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414765 StaticSocketDataProvider data;
14766 data.set_connect_data(mock_connect);
14767 session_deps_.socket_factory->AddSocketDataProvider(&data);
14768
14769 TestCompletionCallback callback;
14770
tfarina42834112016-09-22 13:38:2014771 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414773
14774 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114775 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414776
[email protected]79e1fd62013-06-20 06:50:0414777 // We don't care whether this succeeds or fails, but it shouldn't crash.
14778 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614779 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714780
14781 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614782 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714783 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114784 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914785
14786 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614787 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914788 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414789}
14790
bncd16676a2016-07-20 16:23:0114791TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414792 HttpRequestInfo request;
14793 request.method = "GET";
bncce36dca22015-04-21 22:11:2314794 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414795
danakj1fd259a02016-04-16 03:17:0914796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414798
ttuttled9dbc652015-09-29 20:00:5914799 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414800 StaticSocketDataProvider data;
14801 data.set_connect_data(mock_connect);
14802 session_deps_.socket_factory->AddSocketDataProvider(&data);
14803
14804 TestCompletionCallback callback;
14805
tfarina42834112016-09-22 13:38:2014806 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414808
14809 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114810 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414811
[email protected]79e1fd62013-06-20 06:50:0414812 // We don't care whether this succeeds or fails, but it shouldn't crash.
14813 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614814 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714815
14816 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614817 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714818 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114819 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914820
14821 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614822 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914823 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414824}
14825
bncd16676a2016-07-20 16:23:0114826TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414827 HttpRequestInfo request;
14828 request.method = "GET";
bncce36dca22015-04-21 22:11:2314829 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414830
danakj1fd259a02016-04-16 03:17:0914831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414833
14834 MockWrite data_writes[] = {
14835 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14836 };
14837 MockRead data_reads[] = {
14838 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14839 };
14840
14841 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14842 data_writes, arraysize(data_writes));
14843 session_deps_.socket_factory->AddSocketDataProvider(&data);
14844
14845 TestCompletionCallback callback;
14846
tfarina42834112016-09-22 13:38:2014847 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414849
14850 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114851 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414852
[email protected]79e1fd62013-06-20 06:50:0414853 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614854 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414855 EXPECT_TRUE(request_headers.HasHeader("Host"));
14856}
14857
bncd16676a2016-07-20 16:23:0114858TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414859 HttpRequestInfo request;
14860 request.method = "GET";
bncce36dca22015-04-21 22:11:2314861 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414862
danakj1fd259a02016-04-16 03:17:0914863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614864 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414865
14866 MockWrite data_writes[] = {
14867 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14868 };
14869 MockRead data_reads[] = {
14870 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14871 };
14872
14873 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14874 data_writes, arraysize(data_writes));
14875 session_deps_.socket_factory->AddSocketDataProvider(&data);
14876
14877 TestCompletionCallback callback;
14878
tfarina42834112016-09-22 13:38:2014879 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414881
14882 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114883 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414884
[email protected]79e1fd62013-06-20 06:50:0414885 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614886 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414887 EXPECT_TRUE(request_headers.HasHeader("Host"));
14888}
14889
bncd16676a2016-07-20 16:23:0114890TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414891 HttpRequestInfo request;
14892 request.method = "GET";
bncce36dca22015-04-21 22:11:2314893 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414894
danakj1fd259a02016-04-16 03:17:0914895 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614896 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414897
14898 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314899 MockWrite(
14900 "GET / HTTP/1.1\r\n"
14901 "Host: www.example.org\r\n"
14902 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414903 };
14904 MockRead data_reads[] = {
14905 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14906 };
14907
14908 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14909 data_writes, arraysize(data_writes));
14910 session_deps_.socket_factory->AddSocketDataProvider(&data);
14911
14912 TestCompletionCallback callback;
14913
tfarina42834112016-09-22 13:38:2014914 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414916
14917 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114918 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414919
[email protected]79e1fd62013-06-20 06:50:0414920 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614921 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414922 EXPECT_TRUE(request_headers.HasHeader("Host"));
14923}
14924
bncd16676a2016-07-20 16:23:0114925TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414926 HttpRequestInfo request;
14927 request.method = "GET";
bncce36dca22015-04-21 22:11:2314928 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414929
danakj1fd259a02016-04-16 03:17:0914930 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614931 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414932
14933 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314934 MockWrite(
14935 "GET / HTTP/1.1\r\n"
14936 "Host: www.example.org\r\n"
14937 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414938 };
14939 MockRead data_reads[] = {
14940 MockRead(ASYNC, ERR_CONNECTION_RESET),
14941 };
14942
14943 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14944 data_writes, arraysize(data_writes));
14945 session_deps_.socket_factory->AddSocketDataProvider(&data);
14946
14947 TestCompletionCallback callback;
14948
tfarina42834112016-09-22 13:38:2014949 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414951
14952 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114953 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414954
[email protected]79e1fd62013-06-20 06:50:0414955 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614956 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414957 EXPECT_TRUE(request_headers.HasHeader("Host"));
14958}
14959
bncd16676a2016-07-20 16:23:0114960TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414961 HttpRequestInfo request;
14962 request.method = "GET";
bncce36dca22015-04-21 22:11:2314963 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414964 request.extra_headers.SetHeader("X-Foo", "bar");
14965
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[] = {
bncce36dca22015-04-21 22:11:2314970 MockWrite(
14971 "GET / HTTP/1.1\r\n"
14972 "Host: www.example.org\r\n"
14973 "Connection: keep-alive\r\n"
14974 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414975 };
14976 MockRead data_reads[] = {
14977 MockRead("HTTP/1.1 200 OK\r\n"
14978 "Content-Length: 5\r\n\r\n"
14979 "hello"),
14980 MockRead(ASYNC, ERR_UNEXPECTED),
14981 };
14982
14983 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14984 data_writes, arraysize(data_writes));
14985 session_deps_.socket_factory->AddSocketDataProvider(&data);
14986
14987 TestCompletionCallback callback;
14988
tfarina42834112016-09-22 13:38:2014989 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414991
14992 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114993 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0414994
14995 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614996 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414997 std::string foo;
14998 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14999 EXPECT_EQ("bar", foo);
15000}
15001
[email protected]bf828982013-08-14 18:01:4715002namespace {
15003
yhiranoa7e05bb2014-11-06 05:40:3915004// Fake HttpStream that simply records calls to SetPriority().
15005class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315006 public base::SupportsWeakPtr<FakeStream> {
15007 public:
15008 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015009 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315010
15011 RequestPriority priority() const { return priority_; }
15012
dchengb03027d2014-10-21 12:00:2015013 int InitializeStream(const HttpRequestInfo* request_info,
15014 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015015 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015016 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315017 return ERR_IO_PENDING;
15018 }
15019
dchengb03027d2014-10-21 12:00:2015020 int SendRequest(const HttpRequestHeaders& request_headers,
15021 HttpResponseInfo* response,
15022 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315023 ADD_FAILURE();
15024 return ERR_UNEXPECTED;
15025 }
15026
dchengb03027d2014-10-21 12:00:2015027 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315028 ADD_FAILURE();
15029 return ERR_UNEXPECTED;
15030 }
15031
dchengb03027d2014-10-21 12:00:2015032 int ReadResponseBody(IOBuffer* buf,
15033 int buf_len,
15034 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315035 ADD_FAILURE();
15036 return ERR_UNEXPECTED;
15037 }
15038
dchengb03027d2014-10-21 12:00:2015039 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315040
dchengb03027d2014-10-21 12:00:2015041 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315042 ADD_FAILURE();
15043 return false;
15044 }
15045
dchengb03027d2014-10-21 12:00:2015046 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315047 ADD_FAILURE();
15048 return false;
15049 }
15050
dchengb03027d2014-10-21 12:00:2015051 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315052
mmenkebd84c392015-09-02 14:12:3415053 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315054
sclittle4de1bab92015-09-22 21:28:2415055 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915056 ADD_FAILURE();
15057 return 0;
15058 }
15059
sclittlebe1ccf62015-09-02 19:40:3615060 int64_t GetTotalSentBytes() const override {
15061 ADD_FAILURE();
15062 return 0;
15063 }
15064
dchengb03027d2014-10-21 12:00:2015065 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315066 ADD_FAILURE();
15067 return false;
15068 }
15069
rchcd379012017-04-12 21:53:3215070 bool GetAlternativeService(
15071 AlternativeService* alternative_service) const override {
15072 ADD_FAILURE();
15073 return false;
15074 }
15075
dchengb03027d2014-10-21 12:00:2015076 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15077
15078 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315079 ADD_FAILURE();
15080 }
15081
ttuttled9dbc652015-09-29 20:00:5915082 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15083
nharper78e6d2b2016-09-21 05:42:3515084 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15085 TokenBindingType tb_type,
15086 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415087 ADD_FAILURE();
15088 return ERR_NOT_IMPLEMENTED;
15089 }
15090
dchengb03027d2014-10-21 12:00:2015091 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315092
zhongyica364fbb2015-12-12 03:39:1215093 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15094
dchengb03027d2014-10-21 12:00:2015095 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315096
yhiranoa7e05bb2014-11-06 05:40:3915097 HttpStream* RenewStreamForAuth() override { return NULL; }
15098
[email protected]e86839fd2013-08-14 18:29:0315099 private:
15100 RequestPriority priority_;
15101
15102 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15103};
15104
15105// Fake HttpStreamRequest that simply records calls to SetPriority()
15106// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715107class FakeStreamRequest : public HttpStreamRequest,
15108 public base::SupportsWeakPtr<FakeStreamRequest> {
15109 public:
[email protected]e86839fd2013-08-14 18:29:0315110 FakeStreamRequest(RequestPriority priority,
15111 HttpStreamRequest::Delegate* delegate)
15112 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415113 delegate_(delegate),
15114 websocket_stream_create_helper_(NULL) {}
15115
15116 FakeStreamRequest(RequestPriority priority,
15117 HttpStreamRequest::Delegate* delegate,
15118 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15119 : priority_(priority),
15120 delegate_(delegate),
15121 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315122
dchengb03027d2014-10-21 12:00:2015123 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715124
15125 RequestPriority priority() const { return priority_; }
15126
[email protected]831e4a32013-11-14 02:14:4415127 const WebSocketHandshakeStreamBase::CreateHelper*
15128 websocket_stream_create_helper() const {
15129 return websocket_stream_create_helper_;
15130 }
15131
[email protected]e86839fd2013-08-14 18:29:0315132 // Create a new FakeStream and pass it to the request's
15133 // delegate. Returns a weak pointer to the FakeStream.
15134 base::WeakPtr<FakeStream> FinishStreamRequest() {
15135 FakeStream* fake_stream = new FakeStream(priority_);
15136 // Do this before calling OnStreamReady() as OnStreamReady() may
15137 // immediately delete |fake_stream|.
15138 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
15139 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
15140 return weak_stream;
15141 }
15142
asanka681f02d2017-02-22 17:06:3915143 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715144 ADD_FAILURE();
15145 return ERR_UNEXPECTED;
15146 }
15147
dchengb03027d2014-10-21 12:00:2015148 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715149 ADD_FAILURE();
15150 return LoadState();
15151 }
15152
dchengb03027d2014-10-21 12:00:2015153 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715154
bnc94c92842016-09-21 15:22:5215155 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715156
bnc6227b26e2016-08-12 02:00:4315157 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715158
dchengb03027d2014-10-21 12:00:2015159 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715160
ttuttle1f2d7e92015-04-28 16:17:4715161 const ConnectionAttempts& connection_attempts() const override {
15162 static ConnectionAttempts no_attempts;
15163 return no_attempts;
15164 }
15165
[email protected]bf828982013-08-14 18:01:4715166 private:
15167 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315168 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415169 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715170
15171 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15172};
15173
15174// Fake HttpStreamFactory that vends FakeStreamRequests.
15175class FakeStreamFactory : public HttpStreamFactory {
15176 public:
15177 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015178 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715179
15180 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15181 // RequestStream() (which may be NULL if it was destroyed already).
15182 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15183 return last_stream_request_;
15184 }
15185
xunjieli8fb01a72017-05-22 18:38:0015186 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
15187 RequestPriority priority,
15188 const SSLConfig& server_ssl_config,
15189 const SSLConfig& proxy_ssl_config,
15190 HttpStreamRequest::Delegate* delegate,
15191 bool enable_ip_based_pooling,
15192 bool enable_alternative_services,
15193 const NetLogWithSource& net_log) override {
15194 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715195 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli8fb01a72017-05-22 18:38:0015196 return fake_request;
[email protected]bf828982013-08-14 18:01:4715197 }
15198
xunjieli8fb01a72017-05-22 18:38:0015199 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815200 const HttpRequestInfo& info,
15201 RequestPriority priority,
15202 const SSLConfig& server_ssl_config,
15203 const SSLConfig& proxy_ssl_config,
15204 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915205 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615206 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015207 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815208 NOTREACHED();
15209 return nullptr;
15210 }
15211
xunjieli8fb01a72017-05-22 18:38:0015212 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715213 const HttpRequestInfo& info,
15214 RequestPriority priority,
15215 const SSLConfig& server_ssl_config,
15216 const SSLConfig& proxy_ssl_config,
15217 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615218 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915219 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615220 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015221 const NetLogWithSource& net_log) override {
xunjieli8fb01a72017-05-22 18:38:0015222 FakeStreamRequest* fake_request =
15223 new FakeStreamRequest(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415224 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli8fb01a72017-05-22 18:38:0015225 return fake_request;
[email protected]bf828982013-08-14 18:01:4715226 }
15227
dchengb03027d2014-10-21 12:00:2015228 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915229 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715230 ADD_FAILURE();
15231 }
15232
dchengb03027d2014-10-21 12:00:2015233 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715234 ADD_FAILURE();
15235 return NULL;
15236 }
15237
xunjielif5267de2017-01-20 21:18:5715238 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15239 const std::string& parent_absolute_name) const override {
15240 ADD_FAILURE();
15241 }
15242
[email protected]bf828982013-08-14 18:01:4715243 private:
15244 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15245
15246 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15247};
15248
Adam Rice425cf122015-01-19 06:18:2415249// TODO(ricea): Maybe unify this with the one in
15250// url_request_http_job_unittest.cc ?
15251class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15252 public:
danakj1fd259a02016-04-16 03:17:0915253 FakeWebSocketBasicHandshakeStream(
15254 std::unique_ptr<ClientSocketHandle> connection,
15255 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215256 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415257
15258 // Fake implementation of HttpStreamBase methods.
15259 // This ends up being quite "real" because this object has to really send data
15260 // on the mock socket. It might be easier to use the real implementation, but
15261 // the fact that the WebSocket code is not compiled on iOS makes that
15262 // difficult.
15263 int InitializeStream(const HttpRequestInfo* request_info,
15264 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015265 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415266 const CompletionCallback& callback) override {
15267 state_.Initialize(request_info, priority, net_log, callback);
15268 return OK;
15269 }
15270
15271 int SendRequest(const HttpRequestHeaders& request_headers,
15272 HttpResponseInfo* response,
15273 const CompletionCallback& callback) override {
15274 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15275 response, callback);
15276 }
15277
15278 int ReadResponseHeaders(const CompletionCallback& callback) override {
15279 return parser()->ReadResponseHeaders(callback);
15280 }
15281
15282 int ReadResponseBody(IOBuffer* buf,
15283 int buf_len,
15284 const CompletionCallback& callback) override {
15285 NOTREACHED();
15286 return ERR_IO_PENDING;
15287 }
15288
15289 void Close(bool not_reusable) override {
15290 if (parser())
15291 parser()->Close(true);
15292 }
15293
15294 bool IsResponseBodyComplete() const override {
15295 NOTREACHED();
15296 return false;
15297 }
15298
Adam Rice425cf122015-01-19 06:18:2415299 bool IsConnectionReused() const override {
15300 NOTREACHED();
15301 return false;
15302 }
15303 void SetConnectionReused() override { NOTREACHED(); }
15304
mmenkebd84c392015-09-02 14:12:3415305 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415306
sclittle4de1bab92015-09-22 21:28:2415307 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415308 NOTREACHED();
15309 return 0;
15310 }
15311
sclittlebe1ccf62015-09-02 19:40:3615312 int64_t GetTotalSentBytes() const override {
15313 NOTREACHED();
15314 return 0;
15315 }
15316
Adam Rice425cf122015-01-19 06:18:2415317 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15318 NOTREACHED();
15319 return false;
15320 }
15321
rchcd379012017-04-12 21:53:3215322 bool GetAlternativeService(
15323 AlternativeService* alternative_service) const override {
15324 ADD_FAILURE();
15325 return false;
15326 }
15327
Adam Ricecb76ac62015-02-20 05:33:2515328 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415329
15330 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15331 NOTREACHED();
15332 }
15333
ttuttled9dbc652015-09-29 20:00:5915334 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15335
nharper78e6d2b2016-09-21 05:42:3515336 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15337 TokenBindingType tb_type,
15338 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415339 ADD_FAILURE();
15340 return ERR_NOT_IMPLEMENTED;
15341 }
15342
Adam Rice425cf122015-01-19 06:18:2415343 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15344
zhongyica364fbb2015-12-12 03:39:1215345 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15346
Adam Rice425cf122015-01-19 06:18:2415347 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15348
Adam Rice425cf122015-01-19 06:18:2415349 HttpStream* RenewStreamForAuth() override {
15350 NOTREACHED();
15351 return nullptr;
15352 }
15353
15354 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915355 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415356 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915357 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415358 }
15359
15360 private:
15361 HttpStreamParser* parser() const { return state_.parser(); }
15362 HttpBasicState state_;
15363
15364 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15365};
15366
[email protected]831e4a32013-11-14 02:14:4415367// TODO(yhirano): Split this class out into a net/websockets file, if it is
15368// worth doing.
15369class FakeWebSocketStreamCreateHelper :
15370 public WebSocketHandshakeStreamBase::CreateHelper {
15371 public:
bnc615cf2f2017-05-19 18:53:2615372 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915373 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315374 bool using_proxy) override {
bnc615cf2f2017-05-19 18:53:2615375 return base::MakeUnique<FakeWebSocketBasicHandshakeStream>(
15376 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415377 }
15378
dchengb03027d2014-10-21 12:00:2015379 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415380
danakj1fd259a02016-04-16 03:17:0915381 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415382 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915383 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415384 }
15385};
15386
[email protected]bf828982013-08-14 18:01:4715387} // namespace
15388
15389// Make sure that HttpNetworkTransaction passes on its priority to its
15390// stream request on start.
bncd16676a2016-07-20 16:23:0115391TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215393 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715394 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915395 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715396
krasinc06a72a2016-12-21 03:42:4615397 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115398 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715399
wezca1070932016-05-26 20:30:5215400 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715401
[email protected]bf828982013-08-14 18:01:4715402 TestCompletionCallback callback;
15403 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015404 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715405
15406 base::WeakPtr<FakeStreamRequest> fake_request =
15407 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215408 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715409 EXPECT_EQ(LOW, fake_request->priority());
15410}
15411
15412// Make sure that HttpNetworkTransaction passes on its priority
15413// updates to its stream request.
bncd16676a2016-07-20 16:23:0115414TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215416 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715417 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915418 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715419
krasinc06a72a2016-12-21 03:42:4615420 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115421 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715422
[email protected]bf828982013-08-14 18:01:4715423 TestCompletionCallback callback;
15424 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015425 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715426
15427 base::WeakPtr<FakeStreamRequest> fake_request =
15428 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215429 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715430 EXPECT_EQ(LOW, fake_request->priority());
15431
15432 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215433 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715434 EXPECT_EQ(LOWEST, fake_request->priority());
15435}
15436
[email protected]e86839fd2013-08-14 18:29:0315437// Make sure that HttpNetworkTransaction passes on its priority
15438// updates to its stream.
bncd16676a2016-07-20 16:23:0115439TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215441 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315442 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915443 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315444
krasinc06a72a2016-12-21 03:42:4615445 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115446 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315447
[email protected]e86839fd2013-08-14 18:29:0315448 TestCompletionCallback callback;
15449 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015450 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315451
15452 base::WeakPtr<FakeStreamRequest> fake_request =
15453 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215454 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315455 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215456 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315457 EXPECT_EQ(LOW, fake_stream->priority());
15458
15459 trans.SetPriority(LOWEST);
15460 EXPECT_EQ(LOWEST, fake_stream->priority());
15461}
15462
bncd16676a2016-07-20 16:23:0115463TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415464 // The same logic needs to be tested for both ws: and wss: schemes, but this
15465 // test is already parameterised on NextProto, so it uses a loop to verify
15466 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315467 std::string test_cases[] = {"ws://www.example.org/",
15468 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415469 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215471 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415472 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15473 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315474 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915475 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415476
krasinc06a72a2016-12-21 03:42:4615477 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115478 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415479 trans.SetWebSocketHandshakeStreamCreateHelper(
15480 &websocket_stream_create_helper);
15481
[email protected]831e4a32013-11-14 02:14:4415482 TestCompletionCallback callback;
15483 request.method = "GET";
15484 request.url = GURL(test_cases[i]);
15485
15486 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015487 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415488
15489 base::WeakPtr<FakeStreamRequest> fake_request =
15490 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215491 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415492 EXPECT_EQ(&websocket_stream_create_helper,
15493 fake_request->websocket_stream_create_helper());
15494 }
15495}
15496
[email protected]043b68c82013-08-22 23:41:5215497// Tests that when a used socket is returned to the SSL socket pool, it's closed
15498// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115499TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215500 ClientSocketPoolManager::set_max_sockets_per_group(
15501 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15502 ClientSocketPoolManager::set_max_sockets_per_pool(
15503 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15504
15505 // Set up SSL request.
15506
15507 HttpRequestInfo ssl_request;
15508 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315509 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215510
15511 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315512 MockWrite(
15513 "GET / HTTP/1.1\r\n"
15514 "Host: www.example.org\r\n"
15515 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215516 };
15517 MockRead ssl_reads[] = {
15518 MockRead("HTTP/1.1 200 OK\r\n"),
15519 MockRead("Content-Length: 11\r\n\r\n"),
15520 MockRead("hello world"),
15521 MockRead(SYNCHRONOUS, OK),
15522 };
15523 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15524 ssl_writes, arraysize(ssl_writes));
15525 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15526
15527 SSLSocketDataProvider ssl(ASYNC, OK);
15528 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15529
15530 // Set up HTTP request.
15531
15532 HttpRequestInfo http_request;
15533 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315534 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215535
15536 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315537 MockWrite(
15538 "GET / HTTP/1.1\r\n"
15539 "Host: www.example.org\r\n"
15540 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215541 };
15542 MockRead http_reads[] = {
15543 MockRead("HTTP/1.1 200 OK\r\n"),
15544 MockRead("Content-Length: 7\r\n\r\n"),
15545 MockRead("falafel"),
15546 MockRead(SYNCHRONOUS, OK),
15547 };
15548 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15549 http_writes, arraysize(http_writes));
15550 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15551
danakj1fd259a02016-04-16 03:17:0915552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215553
15554 // Start the SSL request.
15555 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615556 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015557 ASSERT_EQ(ERR_IO_PENDING,
15558 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15559 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215560
15561 // Start the HTTP request. Pool should stall.
15562 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615563 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015564 ASSERT_EQ(ERR_IO_PENDING,
15565 http_trans.Start(&http_request, http_callback.callback(),
15566 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115567 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215568
15569 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115570 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215571 std::string response_data;
bnc691fda62016-08-12 00:43:1615572 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215573 EXPECT_EQ("hello world", response_data);
15574
15575 // The SSL socket should automatically be closed, so the HTTP request can
15576 // start.
dcheng48459ac22014-08-26 00:46:4115577 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15578 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215579
15580 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115581 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615582 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215583 EXPECT_EQ("falafel", response_data);
15584
dcheng48459ac22014-08-26 00:46:4115585 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215586}
15587
15588// Tests that when a SSL connection is established but there's no corresponding
15589// request that needs it, the new socket is closed if the transport socket pool
15590// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115591TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215592 ClientSocketPoolManager::set_max_sockets_per_group(
15593 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15594 ClientSocketPoolManager::set_max_sockets_per_pool(
15595 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15596
15597 // Set up an ssl request.
15598
15599 HttpRequestInfo ssl_request;
15600 ssl_request.method = "GET";
15601 ssl_request.url = GURL("https://www.foopy.com/");
15602
15603 // No data will be sent on the SSL socket.
15604 StaticSocketDataProvider ssl_data;
15605 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15606
15607 SSLSocketDataProvider ssl(ASYNC, OK);
15608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15609
15610 // Set up HTTP request.
15611
15612 HttpRequestInfo http_request;
15613 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315614 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215615
15616 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315617 MockWrite(
15618 "GET / HTTP/1.1\r\n"
15619 "Host: www.example.org\r\n"
15620 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215621 };
15622 MockRead http_reads[] = {
15623 MockRead("HTTP/1.1 200 OK\r\n"),
15624 MockRead("Content-Length: 7\r\n\r\n"),
15625 MockRead("falafel"),
15626 MockRead(SYNCHRONOUS, OK),
15627 };
15628 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15629 http_writes, arraysize(http_writes));
15630 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15631
danakj1fd259a02016-04-16 03:17:0915632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215633
15634 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15635 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915636 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915637 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115638 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215639
15640 // Start the HTTP request. Pool should stall.
15641 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615642 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015643 ASSERT_EQ(ERR_IO_PENDING,
15644 http_trans.Start(&http_request, http_callback.callback(),
15645 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115646 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215647
15648 // The SSL connection will automatically be closed once the connection is
15649 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115650 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215651 std::string response_data;
bnc691fda62016-08-12 00:43:1615652 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215653 EXPECT_EQ("falafel", response_data);
15654
dcheng48459ac22014-08-26 00:46:4115655 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215656}
15657
bncd16676a2016-07-20 16:23:0115658TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915659 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215660 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715661 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215662 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415663
15664 HttpRequestInfo request;
15665 request.method = "POST";
15666 request.url = GURL("http://www.foo.com/");
15667 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415668
danakj1fd259a02016-04-16 03:17:0915669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615670 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415671 // Send headers successfully, but get an error while sending the body.
15672 MockWrite data_writes[] = {
15673 MockWrite("POST / HTTP/1.1\r\n"
15674 "Host: www.foo.com\r\n"
15675 "Connection: keep-alive\r\n"
15676 "Content-Length: 3\r\n\r\n"),
15677 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15678 };
15679
15680 MockRead data_reads[] = {
15681 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15682 MockRead("hello world"),
15683 MockRead(SYNCHRONOUS, OK),
15684 };
15685 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15686 arraysize(data_writes));
15687 session_deps_.socket_factory->AddSocketDataProvider(&data);
15688
15689 TestCompletionCallback callback;
15690
tfarina42834112016-09-22 13:38:2015691 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415693
15694 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115695 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415696
bnc691fda62016-08-12 00:43:1615697 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215698 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415699
wezca1070932016-05-26 20:30:5215700 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415701 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15702
15703 std::string response_data;
bnc691fda62016-08-12 00:43:1615704 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115705 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415706 EXPECT_EQ("hello world", response_data);
15707}
15708
15709// This test makes sure the retry logic doesn't trigger when reading an error
15710// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115711TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415712 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415714 MockWrite data_writes[] = {
15715 MockWrite("GET / HTTP/1.1\r\n"
15716 "Host: www.foo.com\r\n"
15717 "Connection: keep-alive\r\n\r\n"),
15718 MockWrite("POST / HTTP/1.1\r\n"
15719 "Host: www.foo.com\r\n"
15720 "Connection: keep-alive\r\n"
15721 "Content-Length: 3\r\n\r\n"),
15722 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15723 };
15724
15725 MockRead data_reads[] = {
15726 MockRead("HTTP/1.1 200 Peachy\r\n"
15727 "Content-Length: 14\r\n\r\n"),
15728 MockRead("first response"),
15729 MockRead("HTTP/1.1 400 Not OK\r\n"
15730 "Content-Length: 15\r\n\r\n"),
15731 MockRead("second response"),
15732 MockRead(SYNCHRONOUS, OK),
15733 };
15734 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15735 arraysize(data_writes));
15736 session_deps_.socket_factory->AddSocketDataProvider(&data);
15737
15738 TestCompletionCallback callback;
15739 HttpRequestInfo request1;
15740 request1.method = "GET";
15741 request1.url = GURL("http://www.foo.com/");
15742 request1.load_flags = 0;
15743
bnc87dcefc2017-05-25 12:47:5815744 auto trans1 =
15745 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015746 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415748
15749 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115750 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415751
15752 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215753 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415754
wezca1070932016-05-26 20:30:5215755 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415756 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15757
15758 std::string response_data1;
15759 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115760 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415761 EXPECT_EQ("first response", response_data1);
15762 // Delete the transaction to release the socket back into the socket pool.
15763 trans1.reset();
15764
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(
bnc87dcefc2017-05-25 12:47:5815767 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 request2;
15771 request2.method = "POST";
15772 request2.url = GURL("http://www.foo.com/");
15773 request2.upload_data_stream = &upload_data_stream;
15774 request2.load_flags = 0;
15775
bnc691fda62016-08-12 00:43:1615776 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015777 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415779
15780 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115781 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415782
bnc691fda62016-08-12 00:43:1615783 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215784 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415785
wezca1070932016-05-26 20:30:5215786 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415787 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15788
15789 std::string response_data2;
bnc691fda62016-08-12 00:43:1615790 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115791 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415792 EXPECT_EQ("second response", response_data2);
15793}
15794
bncd16676a2016-07-20 16:23:0115795TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415796 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915797 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215798 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715799 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215800 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415801
15802 HttpRequestInfo request;
15803 request.method = "POST";
15804 request.url = GURL("http://www.foo.com/");
15805 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415806
danakj1fd259a02016-04-16 03:17:0915807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415809 // Send headers successfully, but get an error while sending the body.
15810 MockWrite data_writes[] = {
15811 MockWrite("POST / HTTP/1.1\r\n"
15812 "Host: www.foo.com\r\n"
15813 "Connection: keep-alive\r\n"
15814 "Content-Length: 3\r\n\r\n"
15815 "fo"),
15816 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15817 };
15818
15819 MockRead data_reads[] = {
15820 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15821 MockRead("hello world"),
15822 MockRead(SYNCHRONOUS, OK),
15823 };
15824 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15825 arraysize(data_writes));
15826 session_deps_.socket_factory->AddSocketDataProvider(&data);
15827
15828 TestCompletionCallback callback;
15829
tfarina42834112016-09-22 13:38:2015830 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415832
15833 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115834 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415835
bnc691fda62016-08-12 00:43:1615836 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215837 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415838
wezca1070932016-05-26 20:30:5215839 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415840 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15841
15842 std::string response_data;
bnc691fda62016-08-12 00:43:1615843 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115844 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415845 EXPECT_EQ("hello world", response_data);
15846}
15847
15848// This tests the more common case than the previous test, where headers and
15849// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115850TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715851 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415852
15853 HttpRequestInfo request;
15854 request.method = "POST";
15855 request.url = GURL("http://www.foo.com/");
15856 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415857
danakj1fd259a02016-04-16 03:17:0915858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415860 // Send headers successfully, but get an error while sending the body.
15861 MockWrite data_writes[] = {
15862 MockWrite("POST / HTTP/1.1\r\n"
15863 "Host: www.foo.com\r\n"
15864 "Connection: keep-alive\r\n"
15865 "Transfer-Encoding: chunked\r\n\r\n"),
15866 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15867 };
15868
15869 MockRead data_reads[] = {
15870 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15871 MockRead("hello world"),
15872 MockRead(SYNCHRONOUS, OK),
15873 };
15874 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15875 arraysize(data_writes));
15876 session_deps_.socket_factory->AddSocketDataProvider(&data);
15877
15878 TestCompletionCallback callback;
15879
tfarina42834112016-09-22 13:38:2015880 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415882 // Make sure the headers are sent before adding a chunk. This ensures that
15883 // they can't be merged with the body in a single send. Not currently
15884 // necessary since a chunked body is never merged with headers, but this makes
15885 // the test more future proof.
15886 base::RunLoop().RunUntilIdle();
15887
mmenkecbc2b712014-10-09 20:29:0715888 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415889
15890 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115891 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415892
bnc691fda62016-08-12 00:43:1615893 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215894 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415895
wezca1070932016-05-26 20:30:5215896 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415897 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15898
15899 std::string response_data;
bnc691fda62016-08-12 00:43:1615900 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115901 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415902 EXPECT_EQ("hello world", response_data);
15903}
15904
bncd16676a2016-07-20 16:23:0115905TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915906 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215907 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715908 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215909 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415910
15911 HttpRequestInfo request;
15912 request.method = "POST";
15913 request.url = GURL("http://www.foo.com/");
15914 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415915
danakj1fd259a02016-04-16 03:17:0915916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415918
15919 MockWrite data_writes[] = {
15920 MockWrite("POST / HTTP/1.1\r\n"
15921 "Host: www.foo.com\r\n"
15922 "Connection: keep-alive\r\n"
15923 "Content-Length: 3\r\n\r\n"),
15924 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15925 };
15926
15927 MockRead data_reads[] = {
15928 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15929 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15930 MockRead("hello world"),
15931 MockRead(SYNCHRONOUS, OK),
15932 };
15933 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15934 arraysize(data_writes));
15935 session_deps_.socket_factory->AddSocketDataProvider(&data);
15936
15937 TestCompletionCallback callback;
15938
tfarina42834112016-09-22 13:38:2015939 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415941
15942 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115943 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415944
bnc691fda62016-08-12 00:43:1615945 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215946 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415947
wezca1070932016-05-26 20:30:5215948 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415949 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15950
15951 std::string response_data;
bnc691fda62016-08-12 00:43:1615952 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115953 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415954 EXPECT_EQ("hello world", response_data);
15955}
15956
bncd16676a2016-07-20 16:23:0115957TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915958 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215959 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715960 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215961 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415962
15963 HttpRequestInfo request;
15964 request.method = "POST";
15965 request.url = GURL("http://www.foo.com/");
15966 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415967
danakj1fd259a02016-04-16 03:17:0915968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415970 // Send headers successfully, but get an error while sending the body.
15971 MockWrite data_writes[] = {
15972 MockWrite("POST / HTTP/1.1\r\n"
15973 "Host: www.foo.com\r\n"
15974 "Connection: keep-alive\r\n"
15975 "Content-Length: 3\r\n\r\n"),
15976 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15977 };
15978
15979 MockRead data_reads[] = {
15980 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15981 MockRead("hello world"),
15982 MockRead(SYNCHRONOUS, OK),
15983 };
15984 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15985 arraysize(data_writes));
15986 session_deps_.socket_factory->AddSocketDataProvider(&data);
15987
15988 TestCompletionCallback callback;
15989
tfarina42834112016-09-22 13:38:2015990 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115991 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415992
15993 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115994 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415995}
15996
bncd16676a2016-07-20 16:23:0115997TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415998 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915999 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216000 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716001 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216002 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416003
16004 HttpRequestInfo request;
16005 request.method = "POST";
16006 request.url = GURL("http://www.foo.com/");
16007 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416008
danakj1fd259a02016-04-16 03:17:0916009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416011 // Send headers successfully, but get an error while sending the body.
16012 MockWrite data_writes[] = {
16013 MockWrite("POST / HTTP/1.1\r\n"
16014 "Host: www.foo.com\r\n"
16015 "Connection: keep-alive\r\n"
16016 "Content-Length: 3\r\n\r\n"),
16017 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16018 };
16019
16020 MockRead data_reads[] = {
16021 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16022 MockRead("HTTP/1.0 302 Redirect\r\n"),
16023 MockRead("Location: http://somewhere-else.com/\r\n"),
16024 MockRead("Content-Length: 0\r\n\r\n"),
16025 MockRead(SYNCHRONOUS, OK),
16026 };
16027 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16028 arraysize(data_writes));
16029 session_deps_.socket_factory->AddSocketDataProvider(&data);
16030
16031 TestCompletionCallback callback;
16032
tfarina42834112016-09-22 13:38:2016033 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416035
16036 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116037 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416038}
16039
bncd16676a2016-07-20 16:23:0116040TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916041 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216042 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716043 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216044 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416045
16046 HttpRequestInfo request;
16047 request.method = "POST";
16048 request.url = GURL("http://www.foo.com/");
16049 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416050
danakj1fd259a02016-04-16 03:17:0916051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416053 // Send headers successfully, but get an error while sending the body.
16054 MockWrite data_writes[] = {
16055 MockWrite("POST / HTTP/1.1\r\n"
16056 "Host: www.foo.com\r\n"
16057 "Connection: keep-alive\r\n"
16058 "Content-Length: 3\r\n\r\n"),
16059 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16060 };
16061
16062 MockRead data_reads[] = {
16063 MockRead("HTTP 0.9 rocks!"),
16064 MockRead(SYNCHRONOUS, OK),
16065 };
16066 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16067 arraysize(data_writes));
16068 session_deps_.socket_factory->AddSocketDataProvider(&data);
16069
16070 TestCompletionCallback callback;
16071
tfarina42834112016-09-22 13:38:2016072 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416074
16075 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116076 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416077}
16078
bncd16676a2016-07-20 16:23:0116079TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916080 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216081 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716082 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216083 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416084
16085 HttpRequestInfo request;
16086 request.method = "POST";
16087 request.url = GURL("http://www.foo.com/");
16088 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416089
danakj1fd259a02016-04-16 03:17:0916090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416092 // Send headers successfully, but get an error while sending the body.
16093 MockWrite data_writes[] = {
16094 MockWrite("POST / HTTP/1.1\r\n"
16095 "Host: www.foo.com\r\n"
16096 "Connection: keep-alive\r\n"
16097 "Content-Length: 3\r\n\r\n"),
16098 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16099 };
16100
16101 MockRead data_reads[] = {
16102 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16103 MockRead(SYNCHRONOUS, OK),
16104 };
16105 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16106 arraysize(data_writes));
16107 session_deps_.socket_factory->AddSocketDataProvider(&data);
16108
16109 TestCompletionCallback callback;
16110
tfarina42834112016-09-22 13:38:2016111 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116112 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416113
16114 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116115 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416116}
16117
Adam Rice425cf122015-01-19 06:18:2416118// Verify that proxy headers are not sent to the destination server when
16119// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116120TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416121 HttpRequestInfo request;
16122 request.method = "GET";
bncce36dca22015-04-21 22:11:2316123 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416124 AddWebSocketHeaders(&request.extra_headers);
16125
16126 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316127 session_deps_.proxy_service =
16128 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416129
danakj1fd259a02016-04-16 03:17:0916130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416131
16132 // Since a proxy is configured, try to establish a tunnel.
16133 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716134 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16135 "Host: www.example.org:443\r\n"
16136 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416137
16138 // After calling trans->RestartWithAuth(), this is the request we should
16139 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716140 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16141 "Host: www.example.org:443\r\n"
16142 "Proxy-Connection: keep-alive\r\n"
16143 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416144
rsleevidb16bb02015-11-12 23:47:1716145 MockWrite("GET / HTTP/1.1\r\n"
16146 "Host: www.example.org\r\n"
16147 "Connection: Upgrade\r\n"
16148 "Upgrade: websocket\r\n"
16149 "Origin: http://www.example.org\r\n"
16150 "Sec-WebSocket-Version: 13\r\n"
16151 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416152 };
16153
16154 // The proxy responds to the connect with a 407, using a persistent
16155 // connection.
16156 MockRead data_reads[] = {
16157 // No credentials.
16158 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16159 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416160 MockRead("Content-Length: 0\r\n"),
16161 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416162
16163 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16164
16165 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16166 MockRead("Upgrade: websocket\r\n"),
16167 MockRead("Connection: Upgrade\r\n"),
16168 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16169 };
16170
16171 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16172 arraysize(data_writes));
16173 session_deps_.socket_factory->AddSocketDataProvider(&data);
16174 SSLSocketDataProvider ssl(ASYNC, OK);
16175 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16176
bnc87dcefc2017-05-25 12:47:5816177 auto trans =
16178 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416179 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16180 trans->SetWebSocketHandshakeStreamCreateHelper(
16181 &websocket_stream_create_helper);
16182
16183 {
16184 TestCompletionCallback callback;
16185
tfarina42834112016-09-22 13:38:2016186 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416188
16189 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116190 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416191 }
16192
16193 const HttpResponseInfo* response = trans->GetResponseInfo();
16194 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216195 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416196 EXPECT_EQ(407, response->headers->response_code());
16197
16198 {
16199 TestCompletionCallback callback;
16200
16201 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16202 callback.callback());
robpercival214763f2016-07-01 23:27:0116203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416204
16205 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116206 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416207 }
16208
16209 response = trans->GetResponseInfo();
16210 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216211 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416212
16213 EXPECT_EQ(101, response->headers->response_code());
16214
16215 trans.reset();
16216 session->CloseAllConnections();
16217}
16218
16219// Verify that proxy headers are not sent to the destination server when
16220// establishing a tunnel for an insecure WebSocket connection.
16221// This requires the authentication info to be injected into the auth cache
16222// due to crbug.com/395064
16223// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116224TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416225 HttpRequestInfo request;
16226 request.method = "GET";
bncce36dca22015-04-21 22:11:2316227 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416228 AddWebSocketHeaders(&request.extra_headers);
16229
16230 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316231 session_deps_.proxy_service =
16232 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416233
danakj1fd259a02016-04-16 03:17:0916234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416235
16236 MockWrite data_writes[] = {
16237 // Try to establish a tunnel for the WebSocket connection, with
16238 // credentials. Because WebSockets have a separate set of socket pools,
16239 // they cannot and will not use the same TCP/IP connection as the
16240 // preflight HTTP request.
16241 MockWrite(
bncce36dca22015-04-21 22:11:2316242 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16243 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416244 "Proxy-Connection: keep-alive\r\n"
16245 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16246
16247 MockWrite(
16248 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316249 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416250 "Connection: Upgrade\r\n"
16251 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316252 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416253 "Sec-WebSocket-Version: 13\r\n"
16254 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16255 };
16256
16257 MockRead data_reads[] = {
16258 // HTTP CONNECT with credentials.
16259 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16260
16261 // WebSocket connection established inside tunnel.
16262 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16263 MockRead("Upgrade: websocket\r\n"),
16264 MockRead("Connection: Upgrade\r\n"),
16265 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16266 };
16267
16268 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16269 arraysize(data_writes));
16270 session_deps_.socket_factory->AddSocketDataProvider(&data);
16271
16272 session->http_auth_cache()->Add(
16273 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16274 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16275
bnc87dcefc2017-05-25 12:47:5816276 auto trans =
16277 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416278 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16279 trans->SetWebSocketHandshakeStreamCreateHelper(
16280 &websocket_stream_create_helper);
16281
16282 TestCompletionCallback callback;
16283
tfarina42834112016-09-22 13:38:2016284 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416286
16287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116288 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416289
16290 const HttpResponseInfo* response = trans->GetResponseInfo();
16291 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216292 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416293
16294 EXPECT_EQ(101, response->headers->response_code());
16295
16296 trans.reset();
16297 session->CloseAllConnections();
16298}
16299
bncd16676a2016-07-20 16:23:0116300TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916301 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216302 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716303 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216304 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216305
16306 HttpRequestInfo request;
16307 request.method = "POST";
16308 request.url = GURL("http://www.foo.com/");
16309 request.upload_data_stream = &upload_data_stream;
16310
danakj1fd259a02016-04-16 03:17:0916311 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616312 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216313 MockWrite data_writes[] = {
16314 MockWrite("POST / HTTP/1.1\r\n"
16315 "Host: www.foo.com\r\n"
16316 "Connection: keep-alive\r\n"
16317 "Content-Length: 3\r\n\r\n"),
16318 MockWrite("foo"),
16319 };
16320
16321 MockRead data_reads[] = {
16322 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16323 MockRead(SYNCHRONOUS, OK),
16324 };
16325 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16326 arraysize(data_writes));
16327 session_deps_.socket_factory->AddSocketDataProvider(&data);
16328
16329 TestCompletionCallback callback;
16330
16331 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016332 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116333 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216334
16335 std::string response_data;
bnc691fda62016-08-12 00:43:1616336 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216337
16338 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616339 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216340 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616341 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216342}
16343
bncd16676a2016-07-20 16:23:0116344TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916345 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216346 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716347 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216348 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216349
16350 HttpRequestInfo request;
16351 request.method = "POST";
16352 request.url = GURL("http://www.foo.com/");
16353 request.upload_data_stream = &upload_data_stream;
16354
danakj1fd259a02016-04-16 03:17:0916355 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616356 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216357 MockWrite data_writes[] = {
16358 MockWrite("POST / HTTP/1.1\r\n"
16359 "Host: www.foo.com\r\n"
16360 "Connection: keep-alive\r\n"
16361 "Content-Length: 3\r\n\r\n"),
16362 MockWrite("foo"),
16363 };
16364
16365 MockRead data_reads[] = {
16366 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16367 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16368 MockRead(SYNCHRONOUS, OK),
16369 };
16370 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16371 arraysize(data_writes));
16372 session_deps_.socket_factory->AddSocketDataProvider(&data);
16373
16374 TestCompletionCallback callback;
16375
16376 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016377 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116378 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216379
16380 std::string response_data;
bnc691fda62016-08-12 00:43:1616381 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216382
16383 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616384 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216385 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616386 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216387}
16388
bncd16676a2016-07-20 16:23:0116389TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216390 ChunkedUploadDataStream upload_data_stream(0);
16391
16392 HttpRequestInfo request;
16393 request.method = "POST";
16394 request.url = GURL("http://www.foo.com/");
16395 request.upload_data_stream = &upload_data_stream;
16396
danakj1fd259a02016-04-16 03:17:0916397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616398 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216399 // Send headers successfully, but get an error while sending the body.
16400 MockWrite data_writes[] = {
16401 MockWrite("POST / HTTP/1.1\r\n"
16402 "Host: www.foo.com\r\n"
16403 "Connection: keep-alive\r\n"
16404 "Transfer-Encoding: chunked\r\n\r\n"),
16405 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16406 };
16407
16408 MockRead data_reads[] = {
16409 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16410 MockRead(SYNCHRONOUS, OK),
16411 };
16412 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16413 arraysize(data_writes));
16414 session_deps_.socket_factory->AddSocketDataProvider(&data);
16415
16416 TestCompletionCallback callback;
16417
16418 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016419 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216420
16421 base::RunLoop().RunUntilIdle();
16422 upload_data_stream.AppendData("f", 1, false);
16423
16424 base::RunLoop().RunUntilIdle();
16425 upload_data_stream.AppendData("oo", 2, true);
16426
robpercival214763f2016-07-01 23:27:0116427 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216428
16429 std::string response_data;
bnc691fda62016-08-12 00:43:1616430 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216431
16432 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616433 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216434 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616435 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216436}
16437
rdsmith1d343be52016-10-21 20:37:5016438// Confirm that transactions whose throttle is created in (and stays in)
16439// the unthrottled state are not blocked.
16440TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16441 TestNetworkStreamThrottler* throttler(nullptr);
16442 std::unique_ptr<HttpNetworkSession> session(
16443 CreateSessionWithThrottler(&session_deps_, &throttler));
16444
16445 // Send a simple request and make sure it goes through.
16446 HttpRequestInfo request;
16447 request.method = "GET";
16448 request.url = GURL("http://www.example.org/");
16449
bnc87dcefc2017-05-25 12:47:5816450 auto trans =
16451 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016452
16453 MockWrite data_writes[] = {
16454 MockWrite("GET / HTTP/1.1\r\n"
16455 "Host: www.example.org\r\n"
16456 "Connection: keep-alive\r\n\r\n"),
16457 };
16458 MockRead data_reads[] = {
16459 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16460 MockRead(SYNCHRONOUS, OK),
16461 };
16462 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16463 arraysize(data_writes));
16464 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16465
16466 TestCompletionCallback callback;
16467 trans->Start(&request, callback.callback(), NetLogWithSource());
16468 EXPECT_EQ(OK, callback.WaitForResult());
16469}
16470
16471// Confirm requests can be blocked by a throttler, and are resumed
16472// when the throttle is unblocked.
16473TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16474 TestNetworkStreamThrottler* throttler(nullptr);
16475 std::unique_ptr<HttpNetworkSession> session(
16476 CreateSessionWithThrottler(&session_deps_, &throttler));
16477
16478 // Send a simple request and make sure it goes through.
16479 HttpRequestInfo request;
16480 request.method = "GET";
16481 request.url = GURL("http://www.example.org/");
16482
16483 MockWrite data_writes[] = {
16484 MockWrite("GET / HTTP/1.1\r\n"
16485 "Host: www.example.org\r\n"
16486 "Connection: keep-alive\r\n\r\n"),
16487 };
16488 MockRead data_reads[] = {
16489 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16490 MockRead(SYNCHRONOUS, OK),
16491 };
16492 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16493 arraysize(data_writes));
16494 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16495
16496 // Start a request that will be throttled at start; confirm it
16497 // doesn't complete.
16498 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816499 auto trans =
16500 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016501
16502 TestCompletionCallback callback;
16503 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16504 EXPECT_EQ(ERR_IO_PENDING, rv);
16505
16506 base::RunLoop().RunUntilIdle();
16507 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16508 EXPECT_FALSE(callback.have_result());
16509
16510 // Confirm the request goes on to complete when unthrottled.
16511 throttler->UnthrottleAllRequests();
16512 base::RunLoop().RunUntilIdle();
16513 ASSERT_TRUE(callback.have_result());
16514 EXPECT_EQ(OK, callback.WaitForResult());
16515}
16516
16517// Destroy a request while it's throttled.
16518TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16519 TestNetworkStreamThrottler* throttler(nullptr);
16520 std::unique_ptr<HttpNetworkSession> session(
16521 CreateSessionWithThrottler(&session_deps_, &throttler));
16522
16523 // Send a simple request and make sure it goes through.
16524 HttpRequestInfo request;
16525 request.method = "GET";
16526 request.url = GURL("http://www.example.org/");
16527
16528 MockWrite data_writes[] = {
16529 MockWrite("GET / HTTP/1.1\r\n"
16530 "Host: www.example.org\r\n"
16531 "Connection: keep-alive\r\n\r\n"),
16532 };
16533 MockRead data_reads[] = {
16534 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16535 MockRead(SYNCHRONOUS, OK),
16536 };
16537 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16538 arraysize(data_writes));
16539 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16540
16541 // Start a request that will be throttled at start; confirm it
16542 // doesn't complete.
16543 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816544 auto trans =
16545 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016546
16547 TestCompletionCallback callback;
16548 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16549 EXPECT_EQ(ERR_IO_PENDING, rv);
16550
16551 base::RunLoop().RunUntilIdle();
16552 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16553 EXPECT_FALSE(callback.have_result());
16554
16555 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16556 trans.reset();
16557 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16558}
16559
16560// Confirm the throttler receives SetPriority calls.
16561TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16562 TestNetworkStreamThrottler* throttler(nullptr);
16563 std::unique_ptr<HttpNetworkSession> session(
16564 CreateSessionWithThrottler(&session_deps_, &throttler));
16565
16566 // Send a simple request and make sure it goes through.
16567 HttpRequestInfo request;
16568 request.method = "GET";
16569 request.url = GURL("http://www.example.org/");
16570
16571 MockWrite data_writes[] = {
16572 MockWrite("GET / HTTP/1.1\r\n"
16573 "Host: www.example.org\r\n"
16574 "Connection: keep-alive\r\n\r\n"),
16575 };
16576 MockRead data_reads[] = {
16577 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16578 MockRead(SYNCHRONOUS, OK),
16579 };
16580 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16581 arraysize(data_writes));
16582 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16583
16584 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816585 auto trans = base::MakeUnique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016586 // Start the transaction to associate a throttle with it.
16587 TestCompletionCallback callback;
16588 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16589 EXPECT_EQ(ERR_IO_PENDING, rv);
16590
16591 EXPECT_EQ(0, throttler->num_set_priority_calls());
16592 trans->SetPriority(LOW);
16593 EXPECT_EQ(1, throttler->num_set_priority_calls());
16594 EXPECT_EQ(LOW, throttler->last_priority_set());
16595
16596 throttler->UnthrottleAllRequests();
16597 base::RunLoop().RunUntilIdle();
16598 ASSERT_TRUE(callback.have_result());
16599 EXPECT_EQ(OK, callback.WaitForResult());
16600}
16601
16602// Confirm that unthrottling from a SetPriority call by the
16603// throttler works properly.
16604TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16605 TestNetworkStreamThrottler* throttler(nullptr);
16606 std::unique_ptr<HttpNetworkSession> session(
16607 CreateSessionWithThrottler(&session_deps_, &throttler));
16608
16609 // Send a simple request and make sure it goes through.
16610 HttpRequestInfo request;
16611 request.method = "GET";
16612 request.url = GURL("http://www.example.org/");
16613
16614 MockWrite data_writes[] = {
16615 MockWrite("GET / HTTP/1.1\r\n"
16616 "Host: www.example.org\r\n"
16617 "Connection: keep-alive\r\n\r\n"),
16618 };
16619 MockRead data_reads[] = {
16620 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16621 MockRead(SYNCHRONOUS, OK),
16622 };
16623 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16624 arraysize(data_writes));
16625 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16626
16627 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16628 data_writes, arraysize(data_writes));
16629 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16630
16631 // Start a request that will be throttled at start; confirm it
16632 // doesn't complete.
16633 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816634 auto trans =
16635 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016636
16637 TestCompletionCallback callback;
16638 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16639 EXPECT_EQ(ERR_IO_PENDING, rv);
16640
16641 base::RunLoop().RunUntilIdle();
16642 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16643 EXPECT_FALSE(callback.have_result());
16644
16645 // Create a new request, call SetPriority on it to unthrottle,
16646 // and make sure that allows the original request to complete.
bnc87dcefc2017-05-25 12:47:5816647 auto trans1 = base::MakeUnique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5016648 throttler->set_priority_change_closure(
16649 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16650 base::Unretained(throttler)));
16651
16652 // Start the transaction to associate a throttle with it.
16653 TestCompletionCallback callback1;
16654 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16655 EXPECT_EQ(ERR_IO_PENDING, rv);
16656
16657 trans1->SetPriority(IDLE);
16658
16659 base::RunLoop().RunUntilIdle();
16660 ASSERT_TRUE(callback.have_result());
16661 EXPECT_EQ(OK, callback.WaitForResult());
16662 ASSERT_TRUE(callback1.have_result());
16663 EXPECT_EQ(OK, callback1.WaitForResult());
16664}
16665
16666// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5816667void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5016668
16669// Confirm that destroying a transaction from a SetPriority call by the
16670// throttler works properly.
16671TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16672 TestNetworkStreamThrottler* throttler(nullptr);
16673 std::unique_ptr<HttpNetworkSession> session(
16674 CreateSessionWithThrottler(&session_deps_, &throttler));
16675
16676 // Send a simple request and make sure it goes through.
16677 HttpRequestInfo request;
16678 request.method = "GET";
16679 request.url = GURL("http://www.example.org/");
16680
16681 MockWrite data_writes[] = {
16682 MockWrite("GET / HTTP/1.1\r\n"
16683 "Host: www.example.org\r\n"
16684 "Connection: keep-alive\r\n\r\n"),
16685 };
16686 MockRead data_reads[] = {
16687 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16688 MockRead(SYNCHRONOUS, OK),
16689 };
16690 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16691 arraysize(data_writes));
16692 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16693
16694 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16695 data_writes, arraysize(data_writes));
16696 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16697
16698 // Start a request that will be throttled at start; confirm it
16699 // doesn't complete.
16700 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816701 auto trans =
16702 base::MakeUnique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016703
16704 TestCompletionCallback callback;
16705 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16706 EXPECT_EQ(ERR_IO_PENDING, rv);
16707
16708 base::RunLoop().RunUntilIdle();
16709 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16710 EXPECT_FALSE(callback.have_result());
16711
16712 // Arrange for the set priority call on the above transaction to delete
16713 // the transaction.
bnc87dcefc2017-05-25 12:47:5816714 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5016715 throttler->set_priority_change_closure(
16716 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16717
16718 // Call it and check results (partially a "doesn't crash" test).
16719 trans_ptr->SetPriority(IDLE);
16720 trans_ptr = nullptr; // No longer a valid pointer.
16721
16722 base::RunLoop().RunUntilIdle();
16723 ASSERT_FALSE(callback.have_result());
16724}
16725
nharperb7441ef2016-01-25 23:54:1416726#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116727TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416728 const std::string https_url = "https://www.example.com";
16729 HttpRequestInfo request;
16730 request.url = GURL(https_url);
16731 request.method = "GET";
16732
16733 SSLSocketDataProvider ssl(ASYNC, OK);
16734 ssl.token_binding_negotiated = true;
16735 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616736 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416737 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16738
bnc42331402016-07-25 13:36:1516739 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116740 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16741 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416742 MockRead(ASYNC, ERR_IO_PENDING)};
16743 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16744 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5816745 session_deps_.channel_id_service =
16746 base::MakeUnique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0916747 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416748
16749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16750 TestCompletionCallback callback;
16751 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016752 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1016753
16754 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416755
16756 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16757 HttpRequestHeaders headers;
16758 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16759 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16760}
16761#endif // !defined(OS_IOS)
16762
eustasc7d27da2017-04-06 10:33:2016763void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
16764 const std::string& accept_encoding,
16765 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0316766 const std::string& location,
eustasc7d27da2017-04-06 10:33:2016767 bool should_match) {
16768 HttpRequestInfo request;
16769 request.method = "GET";
16770 request.url = GURL("http://www.foo.com/");
16771 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
16772 accept_encoding);
16773
16774 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
16775 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16776 // Send headers successfully, but get an error while sending the body.
16777 MockWrite data_writes[] = {
16778 MockWrite("GET / HTTP/1.1\r\n"
16779 "Host: www.foo.com\r\n"
16780 "Connection: keep-alive\r\n"
16781 "Accept-Encoding: "),
16782 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
16783 };
16784
sky50576f32017-05-01 19:28:0316785 std::string response_code = "200 OK";
16786 std::string extra;
16787 if (!location.empty()) {
16788 response_code = "301 Redirect\r\nLocation: ";
16789 response_code.append(location);
16790 }
16791
eustasc7d27da2017-04-06 10:33:2016792 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0316793 MockRead("HTTP/1.0 "),
16794 MockRead(response_code.data()),
16795 MockRead("\r\nContent-Encoding: "),
16796 MockRead(content_encoding.data()),
16797 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2016798 MockRead(SYNCHRONOUS, OK),
16799 };
16800 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16801 arraysize(data_writes));
16802 session_deps->socket_factory->AddSocketDataProvider(&data);
16803
16804 TestCompletionCallback callback;
16805
16806 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16808
16809 rv = callback.WaitForResult();
16810 if (should_match) {
16811 EXPECT_THAT(rv, IsOk());
16812 } else {
16813 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
16814 }
16815}
16816
16817TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0316818 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2016819}
16820
16821TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0316822 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
16823 true);
eustasc7d27da2017-04-06 10:33:2016824}
16825
16826TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
16827 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0316828 "", false);
16829}
16830
16831TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
16832 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
16833 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2016834}
16835
[email protected]89ceba9a2009-03-21 03:46:0616836} // namespace net